package Thread;
import java.util.Arrays;
public class PrimeRing {
public static void main(String[] args) {
int length = 22; //素数环的长度
int[] b = new int[length]; //一个数组,用来标识第i个数字是否被使用过。
Arrays.fill(b, 0); //将数组初始化为0,标识所有数字尚未被使用
int[] ring = new int[length]; //用于存放最终素数环的数组
ring[0] = 1; //素数环的第一个数字必然为1(因为是个环,我们从1那一点开始考虑就行了)
if(primeNumRing(b, ring, 1))
printArray(ring);
else
System.out.println("不存在素数环");
}
//负责打印数组,最后输出素数环的时候用得着
public static void printArray(int a[]) {
for(int x:a) {
System.out.print(x+" ");
}
System.out.println();
}
//用递归的方法判断素数环
//数组b用来标识某个数字是否被使用过了,数组ring用来存储素数环
//整数n表示当前正在考察素数环中的第几个数字
private static boolean primeNumRing(int[] b, int[] ring, int n) {
//当最后一个数字考察完毕后,测试一下他加上第一个数字(也就是1)是不是素数
//如果是素数,那么就说明找到了素数环,如果不是,则没有找到
if(n == b.length){
printArray(ring);
return isPrimeNum(ring[n-1]+1);
}
//start是循环的开始点,因为奇数的旁边必然是偶数,偶数的旁边必然是奇数
//因此若前一个数是偶数,那么当前考察的必然全是奇数,反之亦然
//因此,循环的跨度为2
int start = 2-n%2;
//1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
for(int i=start; i<b.length; i+=2) {
//如果当前考察的数字没有被使用过,并且和前一个数字相加的和为素数的话
if(b[i]==0 && isPrimeNum((i+1)+ring[n-1])) {
b[i] = 1; //将其标识设置为"已使用"
ring[n] = i+1; //将其放入素数环中
//如果他后面的所有数字都符合要求,则找到素数环,反之将标识清零后,考察下一个数字
if(primeNumRing(b, ring, n+1))
return true;
else
b[i] = 0;
}
}
return false;
}
//判断一个数是否为素数
//这里没有使用通用的判别方法,一般来讲,素数环都不会超过30个数字
//因此需要判断的最大的数字不会超过60。
//本函数的测试因子最大为11,也就是说凡是小于168(13的平方)的素数都能够被判断,够用了
private static boolean isPrimeNum(int x) {
int[] primeNums = {2, 3, 5, 7, 11};
int i;
for(i=0; i<primeNums.length; i++) {
if(x>primeNums[i] && x%primeNums[i] == 0)
break;
}
return (i==primeNums.length);
}
}
素数环
最新推荐文章于 2020-06-30 18:44:51 发布