Java 俄罗斯娃娃素数

Java 俄罗斯娃娃素数,java,primes,Java,Primes,这个问题是在一次采访中提出的(关于质数) 它们通常被称为可截断素数。 我在维基上找到了这段代码 public static void main(String[] args){ final int MAX = 1000000; //Sieve of Eratosthenes (using BitSet only for odd numbers) BitSet primeList = new BitSet(MAX>>1); primeList.se

这个问题是在一次采访中提出的(关于质数)

它们通常被称为可截断素数。 我在维基上找到了这段代码

public static void main(String[] args){

    final int MAX = 1000000;

    //Sieve of Eratosthenes (using BitSet only for odd numbers)
    BitSet primeList = new BitSet(MAX>>1); 
    primeList.set(0,primeList.size(),true); 

    int sqroot = (int) Math.sqrt(MAX); 
    primeList.clear(0); 
    for(int num = 3; num <= sqroot; num+=2) 
    { 
        if( primeList.get(num >> 1) ) 
        { 
            int inc = num << 1;
            for(int factor = num * num; factor < MAX; factor += inc) 
            { 
                //if( ((factor) & 1) == 1) 
                //{ 
                primeList.clear(factor >> 1); 
                //} 
            } 
        } 
    }


    //Find Largest Truncatable Prime. (so we start from 1000000 - 1
    int rightTrunc = -1, leftTrunc = -1;
    for(int prime = (MAX - 1) | 1; prime >= 3; prime -= 2)
    {
        if(primeList.get(prime>>1))
        {
            //Already found Right Truncatable Prime?
            if(rightTrunc == -1)
            {
                int right = prime;
                while(right > 0 && primeList.get(right >> 1)) right /= 10;
                if(right == 0) rightTrunc = prime;
            }

            //Already found Left Truncatable Prime?
            if(leftTrunc == -1 )
            {
                //Left Truncation
                String left = Integer.toString(prime);
                if(!left.contains("0"))
                {
                    while( left.length() > 0 ){
                        int iLeft = Integer.parseInt(left);
                        if(!primeList.get( iLeft >> 1)) break;
                        left = left.substring(1);
                    }
                    if(left.length() == 0) leftTrunc = prime;
                }
            }
            if(leftTrunc != -1 && rightTrunc != -1) //Found both? then Stop loop
            {
                break;
            }
        }
    }
    System.out.println("Left  Truncatable : " + leftTrunc);
    System.out.println("Right Truncatable : " + rightTrunc);
}
但我不能解决这个特殊的俄罗斯娃娃素数问题,比如,如果你有一个素数,你去掉这个素数的左或右数字,那么结果是不是素数


我是新手,请原谅我的错误。

您的问题是使用此代码还是解决问题


如果要解决它,您可以使用筛选算法生成素数,然后检查元素是否为素数(如果为素数,则检查元素/10是否也是素数)

您的问题是使用此代码还是解决问题


如果要解决它,您可以使用筛选算法生成素数,然后检查元素是否为素数(如果为素数,则检查元素/10是否也是素数)

让我们从一个简单的假设开始,即我们知道如何编写代码来检测值是否为素数。在一次编码面试中,他们不太可能指望你拿出“埃拉托什尼筛子”。您应该从处理
x特殊情况的简单代码开始,让我们从一个简单的假设开始,即我们知道如何编写代码来检测值是否为素数。在一次编码面试中,他们不太可能指望你拿出“埃拉托什尼筛子”。您应该从处理
x特殊情况的简单代码开始让我们从头开始:

根据您提供的问题链接:

“俄罗斯娃娃素数是 其右位可以重复删除的素数,并且 仍然是最好的。”

我假设您有一个函数
boolean isPrime(int)
来确定一个数字是否为素数

通过谷歌搜索,我们会发现73939133的右截断素数是83,这使得暴力成为一种可行的选择;但这里可以使用一些优化技术:

  • 因为我们右截断,我们可以安全地消除偶数(因为任何偶数都不会是素数,所以由此产生的任何数都不会是素数)
  • 因为任何以5开头的数字都可以被5整除,那么根据我在上一点中提到的相同规则,我们可以消除5
  • 这就给我们留下了包含1、3、7和9的数字

    现在,如果我们想要生成这4个数字的所有可能组合,并且不超过您提到的最大值(1000000),那么只需要4096次迭代

    这种技术的缺点是,我们现在有4096个数字,其中包含可能的非素数,或者由非素数构成的素数,因此不是俄罗斯玩偶素数。我们可以通过循环和检查来消除这些数字;或者更好的是,我们可以更仔细地研究俄罗斯玩偶素数

    通过检查我在上面的链接中引用的规则,我们发现俄罗斯玩偶素数是素数,其右数字可以反复删除,并且仍然是素数(因此仍然是俄罗斯玩偶素数,给出了反复删除的单词)

    这意味着我们可以从最小的一位数俄罗斯玩偶素数开始工作,使用我们上面使用的我们这一代的魔法,因为由俄罗斯玩偶素数形成的任何素数都是俄罗斯玩偶素数,我们可以在早期消除非素数,从而得到一个干净的俄罗斯玩偶素数列表,同时大大缩短了这样一个程序的运行时间

    请看下面的生成代码:

    void russianDollPrimesGeneration(int x) {
        x *= 10;
        if (x * 10 >= 1000000) return;
        int j;
        for (int i=1; i<=9; i+=2) {
            if (i == 5) continue;
            j = x + i;
            if (isPrime(j)) {
                addToRussianDollPrimesList(j);
                russianDollPrimesGeneration(j);
            }
        }
    }
    
    结束更新注释

    这个小函数将产生一个俄罗斯玩偶素数列表,然后可以搜索我们正在寻找的数字

    另一种方法是使用以下递归函数,但我认为这将更加耗时:

    boolean isRussianDollPrime(int n) {
        if (!isPrime(n)) return false;
        if (n < 10) return true;
        return isRussianDollPrime(n / 10);
    }
    
    布尔isRussianDollPrime(int n){
    如果(!isPrime(n))返回false;
    如果(n<10)返回true;
    返回以色列元(n/10);
    }
    

    此函数可以修改为使用左截断素数。但是,对于左截断素数,基于生成的解决方案将很难实现。

    让我们从头开始:

    根据您提供的问题链接:

    “俄罗斯娃娃素数是 其右位可以重复删除的素数,并且 仍然是最好的。”

    我假设您有一个函数
    boolean isPrime(int)
    来确定一个数字是否为素数

    通过谷歌搜索,我们会发现73939133的右截断素数是83,这使得暴力成为一种可行的选择;但这里可以使用一些优化技术:

  • 因为我们右截断,我们可以安全地消除偶数(因为任何偶数都不会是素数,所以由此产生的任何数都不会是素数)
  • 因为任何以5开头的数字都可以被5整除,那么根据我在上一点中提到的相同规则,我们可以消除5
  • 这就给我们留下了包含1、3、7和9的数字

    现在,如果我们想要生成这4个数字的所有可能组合,并且不超过您提到的最大值(1000000),那么只需要4096次迭代

    这种技术的缺点是,我们现在有4096个数字,其中包含可能的非素数,或者由非素数构成的素数,因此不是俄罗斯玩偶素数。我们可以通过循环和检查来消除这些数字;或者更好的是,我们可以更仔细地研究俄罗斯玩偶素数

    通过检查我在上面的链接中引用的规则,我们发现俄罗斯玩偶素数是素数,其右数字可以反复删除,并且仍然是素数(因此仍然是俄罗斯玩偶素数,反复使用这个词)<
    boolean isRussianPrime(long x)
    {
        boolean result = isPrime(x);
    
        while ((x != 0) && result)
        {
           // chop off the right digit of x
           x = x / 10;
           if (x != 0)
           {
               result = isPrime(x);                 
           }
        }
    
        return result;
    }
    
    void russianDollPrimesGeneration(int x) {
        x *= 10;
        if (x * 10 >= 1000000) return;
        int j;
        for (int i=1; i<=9; i+=2) {
            if (i == 5) continue;
            j = x + i;
            if (isPrime(j)) {
                addToRussianDollPrimesList(j);
                russianDollPrimesGeneration(j);
            }
        }
    }
    
    void generationWrapperFunction(int x) {
        addToRussianDollPrimesList(2);
        russianDollPrimesGeneration(2);
        addToRussianDollPrimesList(5);
        russianDollPrimesGeneration(5);
        russianDollPrimesGeneration(0);
    }
    
    boolean isRussianDollPrime(int n) {
        if (!isPrime(n)) return false;
        if (n < 10) return true;
        return isRussianDollPrime(n / 10);
    }
    
    public static void main(String[] args) {
    
        int x= 373;
        int k;
        int n =x;
    
    
        for ( k= String.valueOf(x).length()-1;k>0;k--){
            System.out.println(n);
            if (isPrime(n)){
                String m=String.valueOf(n).substring(0, k);
                n=Integer.parseInt(m);
                continue;
    
            }else {
                break;
            }
        }
    
        if( k==0){
            System.out.println("Number is Russianl Doll Number "+x);
        }else {
            System.out.println("Number is not Russianl Doll Number "+x);
        }
    
    
    
    }
    
    private static  boolean isPrime(int x) {
        boolean check=true;
        for (int i=2;i<x/2;i++){
            if( (x%i)==0){
    
            check=false;
    
            }
        }
    
        return check;
    }