我需要生成前20个数字,这个数字以1开头,第二个数字是3。 我知道如何检查数字是否为素数,但我发现其他部分存在困难。
也可以有人给我更多练习来生成一些具有特殊性能的数字,因为我发现它们有困难。谢谢
public static int isprime(int x){
for(int i=2;i<x;i++)
if(x%i==0)
return false;
return true; }
答案 0 :(得分:1)
首先,您的isPrime()
方法可能会更有效率。没有必要检查超出数字平方根的因素,因为如果它们存在,你会发现他们的伙伴已经低于平方根。因此,您可以将for
语句的延续条件设置为:
for (int i = 2; i * i <= x; i++)
您也可以通过仅检查2
之后的奇数来大致加倍速度。
假设它们不会太大,您可以将它们转换为字符串,看它是否以"13"
开头。
在Java中,Long.toString()
和String.startsWith()
可能是这项工作的最佳工具。
如果您想自己解决这个问题,那么现在就去做,因为我在下面提供了完整的解决方案。
还在吗?我假设你已经尝试过,或者你只是想要一个解决方案。
例如,参见以下程序:
public class Test {
public static boolean isPrime (long num) {
if ((num % 2) == 0) {
return false;
}
for (long chk = 3; chk * chk <= num; chk += 2) {
if ((num % chk) == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
for (long num = 2, count = 0; count < 20; num++) {
if (Long.toString(num).startsWith("13")) {
if (isPrime(num)) {
count++;
System.out.println ("#" + count + ": " + num);
}
}
}
}
}
生成:
#1: 13
#2: 131
#3: 137
#4: 139
#5: 1301
#6: 1303
#7: 1307
#8: 1319
#9: 1321
#10: 1327
#11: 1361
#12: 1367
#13: 1373
#14: 1381
#15: 1399
#16: 13001
#17: 13003
#18: 13007
#19: 13009
#20: 13033
一个最终位的优化可能会提高性能,如果你是在大数字之后,比如前两百万而不是前二十。
为此,我们从13
开始,然后,只要您的号码以14
开头,就可以跳过一大块候选人(例如14
到129
,或者从140,000
到1,299,999
包括在内)。
这可确保您只检查以13
开头的数字,例如13
,130-139
,1,300-1,399
,13,000-13,999
等等。你也可以通过检查奇数来加快速度。使用部分数字检查也意味着我们不需要进行字符串转换,我们将恢复为仅数字操作,这可能是有益的。
为此,请对代码进行以下更改:
public class Test {
public static boolean isPrime (long num) {
if ((num % 2) == 0) {
return false;
}
for (long chk = 3; chk * chk <= num; chk += 2) {
if ((num % chk) == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
for (long num = 13, end = 14, count = 0; count < 2000000; num += 2) {
// Code to move from 140..0 to 1299..9
if (num >= end) {
end = end * 10;
num = (end / 14) * 13 - 1;
continue;
}
if (isPrime(num)) {
count++;
System.out.println ("#" + count + ": " + num);
}
}
}
}
这将前两百万个数字的运行时间从394秒减少到323秒,下降了18%。
答案 1 :(得分:0)
这适用于您的问题,输出为[13, 131, 137, 139, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 13001, 13003, 13007, 13009, 13033]
但是没关系,因为你的数字很少。如果你想要2000M的第一个数字,那将不是最好的方式。
public void main(String[] args) {
List<Integer> res = new ArrayList<>(20);
int i = 13; // We know that it's not ok before ;)
while (res.size() < 20) {
if (isPrime(i)) {
char[] chars = String.valueOf(i).toCharArray();
if (chars[0] == '1' && chars[1] == '3') {
res.add(i);
}
}
i++;
}
}
// You had an error in your method
private static boolean isPrime(int x) {
for (int i = 2; i < x; i++)
if (x % i == 0)
return false;
return true;
}
答案 2 :(得分:0)
在十进制表示中, d - 数字 n 的第二个数字是3,当且仅当 n <的小数表示的最后一位数字时/ i> div 10 d - 2 是3.数字 m 的十进制表示的最后一位数是3,当且仅当< i> m mod 10 = 3。
见这个例子:
n = 13759具有 d = 5位十进制表示。 n div 10 d - 2 = 13759 div 10 3 = 13759 div 1000 = 13 =
m 的。由于 m mod 10 = 13 mod 10 = 3, n 的十进制表示的第二个数字确实是3。
同样, d - 数字 n 的十进制表示的第一个数字是1,当且仅当 n div 10 < sup> d - 1 = 1。
剩下要做的是弄清楚数字的十进制表示有多少位数。我只会给你以下提示:如果 n ≥10有一个 d - 数字表示,那么 n div 10有一个(< i> d - 1) - 数字表示。此外,对于 n <10,十进制表示始终为1位。
答案 3 :(得分:0)
您需要将数字转换为字符串并检查第一个和第二个字符。
public static boolean hasOneAndThree(int n){
String nString = Integer.toString(n);
if(nString.length() >= 2){
if (nString.charAt(0) == '1' & nString.charAt(1) == '3'){
return true;
}
}
return false;
}
另外,我相信isprime应该返回一个布尔值,而不是一个整数。所以,
public static boolean isprime(int x){
for(int i=0;i<x;i++)
if(x%i==0)
return false;
return true;
}