「Java案例」利用方法求反素数(java编程求素数)

「Java案例」利用方法求反素数(java编程求素数)

编码文章call10242025-08-04 21:49:4114A+A-

编写方法求求反素数

反素数(Emirp)是素数中一个有趣的变种,它本身是素数,反转后的数字也是素数,并且不能是回文数。

反素数基础实现

编写一个程序,要求编写方法 public static boolean isPrime(int num) 判断是否为素数;编写方法 public static int reversal(int number) 实现数字倒置;编写方法 public static boolean isEmirp(int num) 判断是否为反素数;编写方法 public static void showEmirps(int count) 显示前 N 个反素数。

# 源文件保存为“EmirpNumbers.java”

public class EmirpNumbers { public static boolean isPrime(int num) { if (num <= 1) return false; if (num == 2) return true; if (num % 2 == 0) return false; for (int i = 3; i * i <= num; i += 2) { if (num % i == 0) return false; } return true; }
 #技术分享 #掘金
public static int reversal(int number) { int reversed = 0; while (number != 0) { reversed = reversed * 10 + number % 10; number /= 10; } return reversed; }

public static boolean isEmirp(int num) { int reversed = reversal(num); return num != reversed && isPrime(num) && isPrime(reversed); }

public static void showEmirps(int count) { int found = 0, num = 2; while (found < count) { if (isEmirp(num)) { System.out.printf("%6d", num); if (++found % 10 == 0) System.out.println(); } num++; } }

public static void main(String[] args) { System.out.println("前30个反素数:"); showEmirps(30); } }

运行结果

前30个反素数:
    13    17    31    37    71    73    79    97   107   113
   149   157   167   179   199   311   337   347   359   389
   701   709   733   739   743   751   761   769   907   937

代码解析

  • isPrime 方法通过试除法判断素数,优化了偶数检查
  • reversal 方法通过模运算和整数除法实现数字倒置
  • isEmirp 方法组合前两个方法,并排除回文数情况
  • showEmirps 方法从2开始逐个检查,直到找到足够数量的反素数

变体案例解析

双反素数

编写一个程序,要求编写方法 public static boolean isPrime(int num) 判断是否为素数;编写方法 public static int reversal(int number) 实现数字倒置;编写方法 public static boolean isEmirp(int num) 判断是否为反素数;编写方法 public static void showDoubleEmirps(int count) 寻找反转前后都是反素数的特殊数。

# 源文件保存为“EmirpNumbers.java”

public class EmirpNumbers { public static boolean isPrime(int num) { if (num <= 1) return false; if (num == 2) return true; if (num % 2 == 0) return false;

for (int i = 3; i * i <= num; i += 2) { if (num % i == 0) return false; } return true; }

public static int reversal(int number) { int reversed = 0; while (number != 0) { reversed = reversed * 10 + number % 10; number /= 10; } return reversed; }

public static boolean isEmirp(int num) { int reversed = reversal(num); return num != reversed && isPrime(num) && isPrime(reversed); } public static void showDoubleEmirps(int count) { int found = 0, num = 2; while (found < count) { if (isEmirp(num)) { int reversed = reversal(num); if (isEmirp(reversed)) { System.out.printf("(%d, %d) ", num, reversed); if (++found % 3 == 0) System.out.println(); } } num++; } }

public static void main(String[] args) { System.out.println("前30个双反素数:"); showDoubleEmirps(30); } }

运行结果

前30个双反素数:
(13, 31) (17, 71) (31, 13)
(37, 73) (71, 17) (73, 37)
(79, 97) (97, 79) (107, 701)
(113, 311) (149, 941) (157, 751)
(167, 761) (179, 971) (199, 991)
(311, 113) (337, 733) (347, 743)
(359, 953) (389, 983) (701, 107)
(709, 907) (733, 337) (739, 937)
(743, 347) (751, 157) (761, 167)
(769, 967) (907, 709) (937, 739)

发现 :这个方法会找到像(13, 31)、(17, 71)这样的数字对。这类数字在密码学中有特殊意义,因为正反都可以作为密钥。

指定范围内的反素数

编写一个程序,要求编写方法 public static boolean isPrime(int num) 判断是否为素数;编写方法 public static int reversal(int number) 实现数字倒置;编写方法 public static boolean isEmirp(int num) 判断是否为反素数;编写方法 public static void showEmirpsInRange(int start, int end) 查找某个区间内的所有反素数。

# 源文件保存为“EmirpNumbers.java”

public class EmirpNumbers { public static boolean isPrime(int num) { if (num <= 1) return false; if (num == 2) return true; if (num % 2 == 0) return false;

for (int i = 3; i * i <= num; i += 2) { if (num % i == 0) return false; } return true; }

public static int reversal(int number) { int reversed = 0; while (number != 0) { reversed = reversed * 10 + number % 10; number /= 10; } return reversed; }

public static boolean isEmirp(int num) { int reversed = reversal(num); return num != reversed && isPrime(num) && isPrime(reversed); }

public static void showEmirpsInRange(int start, int end) { int count = 0; for (int num = start; num <= end; num++) { if (isEmirp(num)) { System.out.printf("%6d", num); if (++count % 10 == 0) System.out.println(); } } System.out.println("
 在" + start + "到" + end + "区间共找到" + count + "个反素数"); }

public static void main(String[] args) { System.out.print("反素数:"); showEmirpsInRange(0, 30); } }

实用技巧 :当处理大范围时,可以预先筛选素数再判断反素数属性,提高效率。这种方法在数据分析时特别有用,比如统计千万级数字中反素数的分布规律。

反素数链

编写一个程序,要求编写方法 public static boolean isPrime(int num) 判断是否为素数;编写方法 public static int reversal(int number) 实现数字倒置;编写方法 public static boolean isEmirp(int num) 判断是否为反素数;编写方法 public static void findEmirpChain(int length) 查找找能形成多级反转仍为素数的数字链。

# 源文件保存为“EmirpNumbers.java”

public class EmirpNumbers { public static boolean isPrime(int num) { if (num <= 1) return false; if (num == 2) return true; if (num % 2 == 0) return false;

for (int i = 3; i * i <= num; i += 2) { if (num % i == 0) return false; } return true; }

public static int reversal(int number) { int reversed = 0; while (number != 0) { reversed = reversed * 10 + number % 10; number /= 10; } return reversed; }

public static boolean isEmirp(int num) { int reversed = reversal(num); return num != reversed && isPrime(num) && isPrime(reversed); }

public static void findEmirpChain(int length) { int num = 2; while (true) { int current = num; boolean isChain = true;

System.out.print("测试 " + num + ": "); for (int i = 0; i < length; i++) { System.out.print(current + " "); if (!isPrime(current)) { isChain = false; break; } current = reversal(current); if (current == reversal(current)) { isChain = false; break; } }

if (isChain) { System.out.println(" ← 发现长度为" + length + "的反素数链"); break; } System.out.println(); num++; } }

public static void main(String[] args) { findEmirpChain(3); } }

运行结果

测试 2: 2
测试 3: 3
测试 4: 4
测试 5: 5
测试 6: 6
测试 7: 7
测试 8: 8
测试 9: 9
测试 10: 10
测试 11: 11
测试 12: 12
测试 13: 13 31 13  ← 发现长度为3的反素数链

有趣现象 :当 length 设为3时,能找到像13→31→13这样的循环链。这类数字在数学游戏和谜题中很受欢迎。

实战练习题

基础题

优化素数判断 :修改 isPrime 方法,使用6k±1优化法(所有大于3的素数都可以表示为6k±1的形式),减少不必要的检查。

# 源文件保存为“EmirpNumbers.java”

public class EmirpNumbers { public static boolean isPrime(int num) { if (num <= 3) return num > 1; if (num % 2 == 0 || num % 3 == 0) return false;

for (int i = 5; i * i <= num; i += 6) { if (num % i == 0 || num % (i + 2) == 0) { return false; } } return true; }

public static int reversal(int number) { int reversed = 0; while (number != 0) { reversed = reversed * 10 + number % 10; number /= 10; } return reversed; }

public static boolean isEmirp(int num) { int reversed = reversal(num); return num != reversed && isPrime(num) && isPrime(reversed); }

public static void showEmirps(int count) { int found = 0, num = 2; while (found < count) { if (isEmirp(num)) { System.out.printf("%6d", num); if (++found % 10 == 0) System.out.println(); } num++; } }

public static void main(String[] args) { System.out.println("前30个反素数:"); showEmirps(30); } }

提高题

反素数间距分析 :编写方法分析反素数之间的间隔规律,找出最大间隔和平均间隔。

# 源文件保存为“EmirpNumbers.java”

public class EmirpNumbers { public static boolean isPrime(int num) { if (num <= 1) return false; if (num == 2) return true; if (num % 2 == 0) return false;

for (int i = 3; i * i <= num; i += 2) { if (num % i == 0) return false; } return true; }

public static int reversal(int number) { int reversed = 0; while (number != 0) { reversed = reversed * 10 + number % 10; number /= 10; } return reversed; }

public static boolean isEmirp(int num) { int reversed = reversal(num); return num != reversed && isPrime(num) && isPrime(reversed); }

public static void analyzeEmirpGaps(int count) { int prev = 2, maxGap = 0, sumGaps = 0; int found = 0, num = 2;

while (found < count) { if (isEmirp(num)) { int gap = num - prev; if (gap > maxGap) maxGap = gap; sumGaps += gap; prev = num; found++; } num++; }

System.out.println("前"+count+"个反素数分析:"); System.out.println("最大间隔: "+maxGap); System.out.println("平均间隔: "+(double)sumGaps/count); }

public static void main(String[] args) { analyzeEmirpGaps(30); } }

运行结果

前30个反素数分析:
最大间隔: 312
平均间隔: 31.166666666666668

深入理解

反素数问题看似简单,却融合了数论、算法优化和编程技巧。素数判断的优化方法在实际密码学应用中至关重要,RSA 加密算法就依赖大素数的快速判断。数字反转算法在处理身份证校验、信用卡号验证等场景也有广泛应用。

调试这类数字处理程序时,边界条件需要特别注意。比如数字0的反转、整型溢出(反转后的数字可能超过 Integer.MAX_VALUE)、负数处理等。良好的做法是添加参数校验和异常处理:

性能方面,当需要查找大量反素数时,可以考虑使用埃拉托斯特尼筛法预先生成素数表,然后在这个表中查询反转数。这种方法用空间换时间,特别适合需要反复查询的场景。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4