Java队列递归求解素数环问题

思路:

1.创建顺序表SqList的对象L,用于存放素数环中的数据元素;

创建链队列LinkQueue对象Q,用于存放还未加入到素数环中的元素。


2.初始化顺序表L和队列Q:将1加入到顺序表L中,将2~n的自然数全部加到Q队列中。


3.递归,将出队的队首元素p与素数环最后一个数据元素q相加,

若两数之和是素数而且p不是队尾元素,则将p加入到素数环中;

否则说明p暂时无法处理,必须再入队等待,重复此过程。

若p为队尾元素,则还需要判断它与素数环的第一个数据元素的和是否未素数,

若是素数,则将p加入到素数环,求解结束;若不是素数,则重复3,

直到队列为空或者已对队列中每一个数据元素都遍历了一次且未能加入到素数环为止。


实现:用到了之前写的顺序表和链队列

package queueTest;

import linearList.SqList;

public class PrimeRing {

	public boolean isPrime(int num) {
		// 判断是否为素数
		if (num == 1) {
			return false;
		}

		Double n = Math.sqrt(num);// 减小运算量
		for (int i = 2; i <= n.intValue(); i++) {
			if (num % i == 0) {
				return false;
			}
		}
		return true;
	}

	public SqList insertRing(SqList L, LinkQueue Q, int index, int total) throws NumberFormatException, Exception {
		// 在一个顺序表L中插入第index个数,使之与顺序表中第index-1个数的和为素数,
		// 若index等于total,则还需满足第index个数与1的和也为素数,程序返回顺序表
		int count = 0;// 记录遍历队列中数据元素的个数,防止在一次循环中重复遍历
		while (!Q.isEmpty() && count <= total - index) {
			int p = (Integer) Q.poll();// 取队列第一个元素
			int q = (Integer) L.get(L.length() - 1);// 取顺序表最后一个元素
			if (index == total) {// 如果是最后一个元素
				if (isPrime(p + q) && isPrime(p + 1)) {// 而且与顺序表最后一个元素,1都符合
					L.insert(L.length(), p);// 插入到顺序表表尾
					return L;
				} else {
					Q.offer(p);
				}
			} else if (isPrime(p + q)) {// 如果未遍历到最后一个元素
				L.insert(L.length(), p);
				if (insertRing(L, Q, index+1, total) != null) {// 递归
					return L;
				}
				L.remove(L.length()-1);// 移除顺序表表尾数据元素
				Q.offer(p);
			} else {
				Q.offer(p);
			}
			++count;
		}
		return null;
	}
	
	public SqList makePrimeRing(int n)throws Exception{
		//求n个正整数的素数环,并以顺序表返回
		if(n%2!=0){//n为奇数则素数环不存在
			throw new Exception("素数环不存在");
		}
		SqList L=new SqList(n);
		L.insert(0, 1);//初始化顺序表的首结点为1
		LinkQueue Q=new LinkQueue();
		for(int i=2;i<=n;i++){
			Q.offer(i);//初始化队列
		}
		return insertRing(L, Q, 2, n);
	}

	public static void main(String[] args) throws Exception {
		PrimeRing pr=new PrimeRing();
		SqList L=pr.makePrimeRing(8);
		for(int i=0;i<L.length();i++){
			System.out.print(L.get(i)+" ");
		}
	}

}

输出示例:

1 2 3 8 5 6 7 4 


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
素数问题是一种经典的组合数学问题,其描述如下: 给定一个正整数 n,找到长度为 n 的形排列,使得相邻两个数之和均为素数。同一个数字不能被重复使用。 解决素数问题的一种常见方法是使用回溯法。具体地,我们可以定义一个长度为 n 的数组 arr,表示当前已经排列好的数字序列。我们从数字 1 开始,依次尝试将它放到 arr[0] 的位置,然后递归搜索下一个数字。如果当前数字无法满足相邻两个数之和为素数的条件,我们就回溯到上一个数字,继续尝试下一个可行的位置。 为了判断两个数字之和是否为素数,我们可以使用一个预处理表格,将所有可能的素数先计算出来,然后在回溯过程中直接查表即可。 下面是一个简单的 Python 代码实现: ```python def is_prime(n): if n < 2: return False for i in range(2, int(n ** 0.5) + 1): if n % i == 0: return False return True def solve_prime_ring(n): arr = [0] * n primes = [i for i in range(2, 2 * n) if is_prime(i)] def backtrack(k): if k == n: if is_prime(arr[0] + arr[n-1]): print(arr) return for i in range(1, n): if i not in arr and is_prime(i + arr[k-1]): arr[k] = i backtrack(k+1) arr[k] = 0 arr[0] = 1 backtrack(1) solve_prime_ring(5) ``` 这里的 is_prime 函数用来判断一个数是否为素数,primes 则是一个预处理的素数表格。在回溯函数 backtrack 中,我们依次尝试将数字 1 到 n-1 放到 arr[k] 的位置,只有当该数字还未被使用且与前一个数字之和为素数时,才递归搜索下一个数字。当搜索到第 n 个数字时,如果第一个数字与最后一个数字之和为素数,则打印出当前符合要求的排列,否则回溯到上一个数字继续尝试。最终,程序会输出所有符合条件的素数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值