Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.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
Python GCD指数化_Python_Greatest Common Divisor_Exponentiation - Fatal编程技术网

Python GCD指数化

Python GCD指数化,python,greatest-common-divisor,exponentiation,Python,Greatest Common Divisor,Exponentiation,我一直在尝试确定一种较短的计算gcd((a^n+b^n),abs(a-b))的方法。我注意到,如果我计算(使用上面的公式),比如a=100和b=4,从1开始到n(a循环)结束,在某一点,答案变为常数。对于a=100,b=4和n=100,我创建一个从1到n的循环,在每一点,我应用公式,第一个答案(n=1)是8,然后是32,直到n变成100。为了优化,一旦找到两个相等的连续数字,我就跳出循环,最后一个数字(这里是32)就是答案。有人知道计算gcd(a^n+b^n,a-b)的简单公式吗?或者更好的是,

我一直在尝试确定一种较短的计算gcd((a^n+b^n),abs(a-b))的方法。我注意到,如果我计算(使用上面的公式),比如a=100和b=4,从1开始到n(a循环)结束,在某一点,答案变为常数。对于a=100,b=4和n=100,我创建一个从1到n的循环,在每一点,我应用公式,第一个答案(n=1)是8,然后是32,直到n变成100。为了优化,一旦找到两个相等的连续数字,我就跳出循环,最后一个数字(这里是32)就是答案。有人知道计算gcd(a^n+b^n,a-b)的简单公式吗?或者更好的是,我最关心的是,找到(a^n+b^n)的全局公式

注:
1.1我看到两种加速代码的方法

首先,使用数学事实,即

gcd(r, s) = gcd(r % s, s)
(如果
s
不是零)。因此,您不需要完整地计算
a**n+b**n
,只需将其模
a-b
。您可以通过查找
(a**n)%(a-b)
(b**n)%(a-b)
然后添加这些模
a-b

现在,通过查找
a**n
。这涉及一个执行
log2(n)
次的循环。在循环的每个过程中,取剩余的mod
a-b
,以降低数值并加快计算速度

这就是你的算法。通过每一步的平方和模幂运算求
(a**n)%(a-b)
(b**n)%(a-b)
。然后将它们相加,再取一次模数。最后,用
a-b
找到该值的GCD


在某些情况下,例如
a-b
prime,我可以看到一些快捷方式。正如你所注意到的,一个数的幂的模是重复的。然而,对于
a-b
的大值来说,找出它们何时重复是一个非常重要的问题,特别是当
a-b
是复合的且难以考虑的时候。除非您有一些关于
a-b
值和其他参数的附加信息,否则我建议您不要使用重复。如果
a
b
的值较小且事先已知(如您的
a=100
b=4
示例中所示),则重复更具吸引力,您可以预先计算幂模
96
的值


您可能应该使用Python的内置pow函数,而不是使用此代码。有关文档,请参阅@DSM的提示

根据要求,这里是我的求幂例程,通过对给定的数字求平方来实现。当然,也可以进行一些修改。这个版本不会对参数进行错误检查,并且会进行一些微调以降低效率

def exp_by_squaring_mod(x, n, mod):
    """Calculate x**n % mod by squaring. This assumes x and n are non-
    negative integers and mod is a positive integer. This returns 1 for
    0**0.
    """
    result = 1
    x %= mod
    # Reduce n and keep constant the value of result * x**n % mod
    while n:  # while n is not zero
        if n & 1:  # n is odd
            result = result * x % mod
        x = x * x % mod
        n >>= 1  # integer divide by 2
    return result

我看到两种加速代码的方法

首先,使用数学事实,即

gcd(r, s) = gcd(r % s, s)
(如果
s
不是零)。所以你不需要完整地计算
a**n+b**n
,你只需要将它模化为
a-b
。你可以通过找到
(a**n)%(a-b)
(b**n)%(a-b)
然后将这些模加上
a-b

现在,通过查找
a**n
。这涉及一个执行
log2(n)
次的循环。在每次通过循环时,取剩余的mod
a-b
,以降低数值并加快计算

这就是你的算法。在每一步中,通过平方和模求幂找到
(a**n)%(a-b)
(b**n)%(a-b)
。然后将它们相加并再次取模。最后,用
a-b
找到该值的GCD


在某些情况下,例如
a-b
素数,我可以看到一些快捷方式。正如您所注意到的,一个数字的幂的模确实会重复。但是,对于
a-b
的大值来说,找出它们何时重复是一个非常重要的问题,特别是如果
a-b
是复合的并且很难计算的话。除非您有一些额外的al关于
a-b
的值和其他参数的信息,我建议您不要使用重复。如果
a
b
的值很小并且事先知道(如您的示例
a=100
b=4
,重复更具吸引力,您可以预先计算幂模
96
的值


您可能应该使用Python的内置pow函数,而不是使用此代码。有关文档,请参阅@DSM的提示

根据要求,这里是我的求幂例程,通过对给定的数字求平方来实现。当然,也可以进行一些修改。这个版本不会对参数进行错误检查,并且会进行一些微调以降低效率

def exp_by_squaring_mod(x, n, mod):
    """Calculate x**n % mod by squaring. This assumes x and n are non-
    negative integers and mod is a positive integer. This returns 1 for
    0**0.
    """
    result = 1
    x %= mod
    # Reduce n and keep constant the value of result * x**n % mod
    while n:  # while n is not zero
        if n & 1:  # n is odd
            result = result * x % mod
        x = x * x % mod
        n >>= 1  # integer divide by 2
    return result

尝试使用以下方法优化求幂:

def powerBySquaring(x,n):
    if n < 0:
        x = 1 / x
        n = -n
    if n == 0: return 1
    y = 1
    while n > 1:
        if n % 2 == 0:
            x = x * x
            n = n / 2
        else:
            y = x * y
            x = x * x
            n = (n-1)/2
    return x * y
def powerBySquaring(x,n):
如果n<0:
x=1/x
n=-n
如果n==0:返回1
y=1
当n>1时:
如果n%2==0:
x=x*x
n=n/2
其他:
y=x*y
x=x*x
n=(n-1)/2
返回x*y

尝试使用以下方法优化求幂运算:

def powerBySquaring(x,n):
    if n < 0:
        x = 1 / x
        n = -n
    if n == 0: return 1
    y = 1
    while n > 1:
        if n % 2 == 0:
            x = x * x
            n = n / 2
        else:
            y = x * y
            x = x * x
            n = (n-1)/2
    return x * y
def powerBySquaring(x,n):
如果n<0:
x=1/x
n=-n
如果n==0:返回1
y=1
当n>1时:
如果n%2==0:
x=x*x
n=n/2
其他:
y=x*y
x=x*x
n=(n-1)/2
返回x*y

如果您的“主要问题”正在尝试查找
a^n+b^n
,只查找
a**n+b**n
有什么问题吗?尝试计算a^n+b^n,其中a,b最多可达10^10。计算需要10秒以上。如果您处理的是非常大的数字,您应该在问题中添加范围:答案高度依赖于它们的大小。以平方和倍数表示y算法,我建议您使用位运算,而不是
n%2
和<