10亿以内回文质数算法

爱凌寒 2010-10-20 03:14:18
前天在站内看见有人发这样的帖子,这里贴上自己的代码仅供参考。
希望大牛能指出其中的不足,让小子也学学。

package org.michael;

import java.util.ArrayList;
import java.util.List;

public class Test10Y {

/**
* 10Y内的回文质数
* @param strings
*/
public static void main(String... strings) {
long time = System.currentTimeMillis();
System.out.println("now time:" + time+" start........................");
List list = new ArrayList();
for (int i = 0; i < 1000000000; i++) {
//筛掉偶数的回文数
if(i%2!=0){
boolean flag = runbackNum(i);
if(flag==true){
list.add(i);
// System.out.println("-->"+i);
}
}else{
continue;
}
}

System.out.println("end search the runbackNum.........................................................................");
System.out.println("use time:"+(System.currentTimeMillis()-time)/1000+" s");

int temp = list.size();
List listPrime = new ArrayList();
for(int i=0;i<temp;i++){
if(isPrime((Integer)list.get(i))){
listPrime.add(list.get(i));
}
}


System.out.println(listPrime.size());
System.out.println("***************************************************************************************************");
int lengthPrime = listPrime.size();
for(int i=0;i<lengthPrime;i++){
if(i%20==0){
System.out.println("");
}
System.out.print((Integer)listPrime.get(i)+" ");
}
System.out.println("totle time:" + (System.currentTimeMillis()-time)/1000+" s");
}

/**
* 判断回文数
* @param num
* @return
*/
private static boolean runbackNum(int num){
String str = num + "";
int length = str.length();
boolean flag = true;
if (length > 1) {
for (int j = 0; j < length / 2; j++) {
if (str.charAt(j) == str.charAt(length - j - 1)) {
flag = flag && true;
} else {
flag = flag && false;
break;
}
}
}
return flag;

}

/**
* 判断质数
* @param num
* @return
*/
private static boolean isPrime(int num){
boolean isPrime = true;
for(int j=2;j<Math.sqrt(num)+1;j++){
if(num%j==0){
isPrime=false;
break;
}
}
return isPrime;
}
}


...全文
455 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
deadangelyyzz 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 deadangelyyzz 的回复:]
引用 20 楼 xuzhixiongsy 的回复:
引用 19 楼 deadangelyyzz 的回复:

Java code

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
int……
[/Quote]

之前的贴错了

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
int halfLen;
int buffer1;
int k = 0;
int iBuffer;
String s;
boolean flag;

for (int i = 11; i < 100000000;) {
flag = true;
s = String.valueOf(i);
len = s.length();
halfLen = len / 2;

for (int m = 0; m < halfLen; m++) {
if (s.charAt(m) != s.charAt(len - 1 - m)) {
flag = false;
break;
}
}

if (flag) {
iBuffer = i;

buffer1 = (int) Math.pow(10, halfLen);

for (k = halfLen; k < len; k++) {
if (s.charAt(k) == '9') {
buffer1 = buffer1 / 10;

if (k == len - 1) {
i++;
}
} else {
i = i + buffer1;
break;
}
}

if (isZhiShu(iBuffer)) {
System.out.println(iBuffer);
j++;
}

} else {
i = i + 1;

}

}
long t2 = System.currentTimeMillis();
System.out.print(t2 - t1);
System.out.println("ms");
System.out.println("count:" + (j + 10));

}

public static boolean isZhiShu(int i) {
if (i <= 7) {
if (i == 2 || i == 3 || i == 5 || i == 7)
return true;
}
int c = 7;
if (i % 2 == 0)
return false;
if (i % 3 == 0)
return false;
if (i % 5 == 0)
return false;
int end = (int) Math.sqrt(i);
while (c <= end) {
if (i % c == 0) {
return false;
}
c += 4;
if (i % c == 0) {
return false;
}
c += 2;
if (i % c == 0) {
return false;
}
c += 4;
if (i % c == 0) {
return false;
}
c += 2;
if (i % c == 0) {
return false;
}
c += 4;
if (i % c == 0) {
return false;
}
c += 6;
if (i % c == 0) {
return false;
}
c += 2;
if (i % c == 0) {
return false;
}
c += 6;
}
return true;

}
}

deadangelyyzz 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 deadangelyyzz 的回复:]
引用 20 楼 xuzhixiongsy 的回复:
引用 19 楼 deadangelyyzz 的回复:

Java code

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
int……
[/Quote]

isZhiShu方法是没有,因为我用的是checkZhiShu方法,有区别???
你把1亿改成10亿不就行了,算法又没变。时间是10s左右
我的算法是跳过那些根本不可能是回文的数,所以循环次数降低,效率提高了。
例如121是回文,则121到130之间的数不可能为回文,12221为回文,12221到12300之间的数不可能为回文,当然这里面还要考虑类似199991这样的数,会出现连续进位的情况,所以要进行特殊处理。

好好研究数字总结规律吧,看东西要看本质,回文在一定程度上来讲是有规律的


zhuzeitou 2010-10-28
  • 打赏
  • 举报
回复
剪了那么多,已经不暴力了~
爱凌寒 2010-10-25
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 deadangelyyzz 的回复:]

引用 20 楼 xuzhixiongsy 的回复:
引用 19 楼 deadangelyyzz 的回复:

Java code

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
in……
[/Quote]
1.述说暴力搜索和生成在现实生活中的应用
>>检索数据(暴力搜索是比较全面的)
>>一个范围内的全部数据还是用生成会比较现实

2.你的方法:
你缺了个方法叫isZhiShu,这个暂且不说。
说说你的暴力搜索,感觉你好像缺了一个数量级,我没怎么仔细看你这个算法,因为我看到你的for循环的结束时1亿而不是10亿。下面是你的code:
for (int i = 10; i < 100000000;) {
//do something
}
当然我可能会看错,如果我看错你可以纠正我。说说你的算法。
不过建议你把正确的完整的代码贴出来。我们再一起探讨。
本人对代码不对人,如果说话不够客气请谅解。








爱凌寒 2010-10-22
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 deadangelyyzz 的回复:]

Java code

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
int halfLen;
int buff……
[/Quote]
6楼那哥们1s都不到。。。。
deadangelyyzz 2010-10-22
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 xuzhixiongsy 的回复:]
引用 19 楼 deadangelyyzz 的回复:

Java code

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
int halfLen;
int buff……

6楼……
[/Quote]
生成的当然可以那么快了,
我只是想说下暴力搜索判断回文我这样最快了。。。。。。
zhuzeitou 2010-10-21
  • 打赏
  • 举报
回复
回文数长度分奇数和偶数两种,奇数的话中间的那个数字是不影响的

那么我们把长度为2n和2n+1的回文数统一处理
比如对于3位数i=123,很容易得到反转的rev=321,长度len=3和附带的pow=10^3=1000。
我们可以生成6位回文数i*pow+rev=123321,接下来开始生成7位回文数。
首先得到base=i*10=1230,然后做一个j从0到9的循环,计算(base+j)*pow+rev=123j321就是7位回文数

由于题目要求10亿也就是1000000000以内的数,那么i只需要从1到9999就可以了
deadangelyyzz 2010-10-21
  • 打赏
  • 举报
回复

public class HuiWen4 {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
int j = 0;
int len;
int halfLen;
int buffer1;
int k = 0;
int iBuffer;
String s;
boolean flag;

for (int i = 10; i < 100000000;) {
flag = true;
s = String.valueOf(i);
len = s.length();
halfLen = len / 2;

for (int m = 0; m < halfLen; m++) {
if (s.charAt(m) != s.charAt(len - 1 - m)) {
flag = false;
break;
}
}

if (flag) {
iBuffer = i;

buffer1 = (int) Math.pow(10, halfLen);

for (k = halfLen; k < len; k++) {
if (s.charAt(k) == '9') {
buffer1 = buffer1 / 10;

if (k == len - 1) {
i++;
}
} else {
i = i + buffer1;
break;
}
}

if (isZhiShu(iBuffer)) {
System.out.println(iBuffer);
j++;
}

} else {
i = i + 1;

}

}
long t2 = System.currentTimeMillis();
System.out.print(t2 - t1);
System.out.println("ms");
System.out.println("count:" + (j + 4));

}

public static boolean checkZhiShu(int i){
int len = (int) Math.sqrt(i);

for(int j=2;j<=len;j++){
if(len%j == 0){
return false;
}
}

return true;
}
}



10s左右
爱凌寒 2010-10-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zhuzeitou 的回复:]

Java code
public static boolean isPrime(int i) {
if (i < 2)
return false;
if (i % 2 == 0 && i > 2)
return false;
for (int j = 3; j * j <= i; j += 2) {
if ……
[/Quote]
你能不能把那个生成回文数的算法用语言描述一下?
blazingfire 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhuzeitou 的回复:]

暴力搜索判断回文的话效率实在太那啥了……直接生成吧

Java code
public static void main(String[] args) {
for (int i = 1; i < 10000; i++) {
int reverse = reverse(i);
if (reverse % 2 == 0)
cont……
[/Quote]
景仰一番!
爱凌寒 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 keeya0416 的回复:]

比较暴力
想 6 楼说的 直接生成回文数比较好
比如题中是 10 位的
那只要生成 后 5 位就决定了一个数
生成这个数的时候还可以适当剪枝下
如 后 5 位不能是回文 (abcbaabcba = abcba * 100001 显然非质)
末尾非 0, 5 , 2 ,4 ,6 ,8
5位之和非 3 倍数
等等
以上系个人拙见 如误见谅
[/Quote]
你说得对,谢谢。
爱凌寒 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhuzeitou 的回复:]

暴力搜索判断回文的话效率实在太那啥了……直接生成吧

Java code
public static void main(String[] args) {
for (int i = 1; i < 10000; i++) {
int reverse = reverse(i);
if (reverse % 2 == 0)
cont……
[/Quote]

顶这个,很不错的算法。。。
学习了。。。
爱凌寒 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yangsen600 的回复:]

为什么不这样呢?
C/C++ code

isHuiwen(int n);
isZhishu(int n);
/////////////////////
if(isHuiwen(x)==1 && isZhishu(x)==1 )
输出...
[/Quote]
你这个的意思跟我那个的意思是一样的呀?先筛选回文,后筛选质数。
keeya0416 2010-10-20
  • 打赏
  • 举报
回复
比较暴力
想 6 楼说的 直接生成回文数比较好
比如题中是 10 位的
那只要生成 后 5 位就决定了一个数
生成这个数的时候还可以适当剪枝下
如 后 5 位不能是回文 (abcbaabcba = abcba * 100001 显然非质)
末尾非 0, 5 , 2 ,4 ,6 ,8
5位之和非 3 倍数
等等
以上系个人拙见 如误见谅
zhuzeitou 2010-10-20
  • 打赏
  • 举报
回复
看了下lz的算法,除了暴力搜索回文数、上面5楼提到的将两个条件同时判断之外,还有就是判断回文数的方法可以优化

lz采用的是转换成字符串首尾对应判断,但字符串的效率是很低的,可以采用反复对10取余将数字反转判断是否与原数相同来判断
爱凌寒 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xuyang840117 的回复:]

for (int i = 0; i < 1000000000; i++) {
//筛掉偶数的回文数
if(i%2!=0){
boolean flag = runbackNum(i);
if(flag==true){
list.add(i……
[/Quote]
这个学习了。。。。
当时没想到。。。
zhuzeitou 2010-10-20
  • 打赏
  • 举报
回复
public static void main(String[] args) {
for (int i = 1; i < 10000; i++) {
int reverse = reverse(i);
if (reverse % 2 == 0)
continue;
int palindrome = i;
int length = length(i);
int pow = 1;
for (int j = 0; j < length; j++)
pow *= 10;
palindrome = palindrome * pow + reverse;
if (isPrime(palindrome))
System.out.println(palindrome);

int temp = i * 10;
for (int k = 0; k < 10; k++) {
palindrome = temp + k;
palindrome = palindrome * pow + reverse;
if (isPrime(palindrome))
System.out.println(palindrome);
}
}
}


再优化下主干,主要是提取了一些重复计算
凉岑玉 2010-10-20
  • 打赏
  • 举报
回复

纯属学习··
zhuzeitou 2010-10-20
  • 打赏
  • 举报
回复
public static boolean isPrime(int i) {
if (i < 2)
return false;
if (i % 2 == 0 && i > 2)
return false;
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0)
return false;
}
return true;
}


优化下质数判断
zhuzeitou 2010-10-20
  • 打赏
  • 举报
回复
暴力搜索判断回文的话效率实在太那啥了……直接生成吧

public static void main(String[] args) {
for (int i = 1; i < 10000; i++) {
int reverse = reverse(i);
if (reverse % 2 == 0)
continue;
int length = length(i);
int palindrome = i;
for (int j = 0; j < length; j++)
palindrome *= 10;
palindrome += reverse;
if (isPrime(palindrome))
System.out.println(palindrome);

for (int k = 0; k < 10; k++) {
palindrome = i * 10 + k;
for (int j = 0; j < length; j++)
palindrome *= 10;
palindrome += reverse;
if (isPrime(palindrome))
System.out.println(palindrome);
}
}
}

public static boolean isPrime(int i) {
if (i < 2)
return false;
for (int j = 2; j * j <= i; j++) {
if (i % j == 0)
return false;
}
return true;
}

public static int reverse(int i) {
int res = 0;
while (i != 0) {
res *= 10;
res += i % 10;
i /= 10;
}
return res;
}

public static int length(int i) {
int res = 0;
while (i != 0) {
i /= 10;
res++;
}
return res;
}
加载更多回复(5)

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧