Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当p是素数时,如何有效地求gcd(a,b)%p?_Java_Algorithm_Primes_Number Theory_Greatest Common Divisor - Fatal编程技术网

Java 当p是素数时,如何有效地求gcd(a,b)%p?

Java 当p是素数时,如何有效地求gcd(a,b)%p?,java,algorithm,primes,number-theory,greatest-common-divisor,Java,Algorithm,Primes,Number Theory,Greatest Common Divisor,我的方法很简单: 首先,使用欧几里德算法查找gcd(a,b)。 然后用p=10^9+7取出mod 但我需要一种有效的方法(只需要正确的轨道而不是代码): a和b的值可能介于1到10^12之间,而p是prime 10^9+7如果我有你这样的问题,这将是我的解决方案。在我的解决方案中,我检查long的范围是否满足10^12。如您所见,下面的代码给出了18,这意味着它没问题!尽管如此,我还是不喜欢欧几里德的GCD,因为它递归地工作。你的范围真的很大,这会消耗大量内存。所以,我更喜欢 类测试{ 私有

我的方法很简单:

  • 首先,使用欧几里德算法查找
    gcd(a,b)
  • 然后用
    p=10^9+7取出mod
但我需要一种有效的方法(只需要正确的轨道而不是代码):


a
b
的值可能介于
1
10^12
之间,而
p
prime 10^9+7

如果我有你这样的问题,这将是我的解决方案。在我的解决方案中,我检查
long
的范围是否满足
10^12
。如您所见,下面的代码给出了
18
,这意味着它没问题!尽管如此,我还是不喜欢欧几里德的GCD,因为它递归地工作。你的范围真的很大,这会消耗大量内存。所以,我更喜欢

类测试{
私有静态最终长P=(长)数学.pow(10,9)+7;
公共静态void main(字符串[]args){
//检查long是否适用于范围
System.out.println((int)Math.log10(Long.MAX_值));
//你的愿望达到10^12,所以没关系!
int结果=计算(1,(长)数学功率(10,12));
系统输出打印项次(结果);
结果=计算((长)数学功率(10,12),(长)数学功率(10,12));
系统输出打印项次(结果);
}
公共静态整数计算(长a、长b){
返回值(整数)(gcd(a,b)%P);
}
专用静态长gcd(长p、长q){
// https://introcs.cs.princeton.edu/java/23recursion/BinaryGCD.java.html
如果(q==0)返回p;
如果(p==0)返回q;
//p和q偶数
如果((p&1)==0&(q&1)==0)返回gcd(p>>1,q>>1)>1,q);
//p是奇数,q是偶数
否则如果((q&1)==0)返回gcd(p,q>>1);
//p和q奇数,p>=q
否则,如果(p>=q)返回gcd((p-q)>>1,q);
//p和q奇数,p>1);
}
私有静态长欧几里得GCD(长a,长b){返回b==0?a:EuclidianGCD(b,a%b);}
}

您可以从中查看最后一个的答案。此外,如果你坚持使用欧几里德的GCD,试试看,它可能会卡住!我觉得它根本就没有效率。

你的方法有什么问题吗?
尾部递归如何?因此,您不会消耗大量内存,而不仅仅是当前堆栈帧。好吧,既然你说的是
Java
,那么你可能不得不选择其他方法。不过,你可以将欧几里德算法实现为一个循环,与二进制GCD相同,因此它们都可以在没有不必要的堆栈空间使用的情况下实现Yupp!我已经试过欧几里德的GCD了。它占用了太多的内存。我会试一下这个二进制GCD或Stein的算法。谢谢@MdUmair你是在解决8月的CodeChef问题吗?如果您在提交时使用了此代码,那么您将面临剽窃处罚。@saketk21这是一个很好的习惯,我希望每个人都有一天, thanks@saketk21是的,你是对的。我当时正在解决长达8月的CodeChef问题,但我已经知道了Stein的算法。我问这个问题的主要原因不是为了在CodeChef获得分数,而是为了在初学者身上学到一些新的东西。我想知道我是否可以通过使用MMI或其他技术在首要的
class Test {
    private static final long P = (long)Math.pow(10, 9) + 7;

    public static void main(String[] args) {
        // Check whether long is suitable in regards to ranges
        System.out.println((int)Math.log10(Long.MAX_VALUE));
        // Your wish up to 10^12, so it's ok!
        int result = calculate(1, (long) Math.pow(10, 12));
        System.out.println(result);

        result = calculate((long) Math.pow(10, 12), (long) Math.pow(10, 12));
        System.out.println(result);
    }

    public static int calculate(long a, long b) {
        return  (int)(gcd(a, b) % P);
    }

    private static long gcd(long p, long q) {
        // https://introcs.cs.princeton.edu/java/23recursion/BinaryGCD.java.html
        if (q == 0) return p;
        if (p == 0) return q;

        // p and q even
        if ((p & 1) == 0 && (q & 1) == 0) return gcd(p >> 1, q >> 1) << 1;

            // p is even, q is odd
        else if ((p & 1) == 0) return gcd(p >> 1, q);

            // p is odd, q is even
        else if ((q & 1) == 0) return gcd(p, q >> 1);

            // p and q odd, p >= q
        else if (p >= q) return gcd((p-q) >> 1, q);

            // p and q odd, p < q
        else return gcd(p, (q-p) >> 1);
    }

    private static long EuclidianGCD(long a, long b) { return b==0 ? a : EuclidianGCD(b, a%b); }

}