如何生成特殊数字?

时间:2015-01-13 05:12:55

标签: java

我需要生成前20个数字,这个数字以1开头,第二个数字是3。 我知道如何检查数字是否为素数,但我发现其他部分存在困难。

也可以有人给我更多练习来生成一些具有特殊性能的数字,因为我发现它们有困难。谢谢

  public static int isprime(int x){
         for(int i=2;i<x;i++)
               if(x%i==0)
                  return false;
        return true;  }

4 个答案:

答案 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开头,就可以跳过一大块候选人(例如14129,或者从140,0001,299,999包括在内)。

这可确保您只检查以13开头的数字,例如13130-1391,300-1,39913,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;  
}