【问题标题】:Exponentiation for huge numbers by huge numbers用大数对大数求幂
【发布时间】:2019-01-31 20:41:31
【问题描述】:

我有两个巨大的自然数保存为字符串:ab。每个数字最多可以有 150 个字符。我需要在合理的时间内得到 ab 的结果。

我搜索了最佳解决方案,但总是 a 是一个大字符串,而 b - int。

我尝试了简单的解决方案:

string power(string n1, string n2) {
    string result = n1;

    if(n2 == "0")
        return "1";

    do {
        result = multiply(result, n1);
        n2 = decrement(n2);
    }
    while(n2 != "1");

    return result;
}

我怎样才能在更短的时间内得到结果?

【问题讨论】:

  • 你需要这个做什么?一旦你拥有了这种权力,你计划做的下一件事是什么?我怀疑您实际上可能根本不需要计算全部功率。
  • 定义“合理”。还要解释为什么你不能使用现有的“bignum”库。
  • 那你就不用计算功率了。模幂是技巧的名称。
  • @LukasKhuka 递减 10^150 你需要十亿年,我确认你需要更快的方法^^
  • 请提供minimal reproducible example。目前我们不知道你是如何得到结果的。少了多少时间?

标签: c++ algorithm


【解决方案1】:

当你重复使用结果时,你需要计算的更少。

例如: 5^8 = 5^4*5^4 = 5^2*5^2*5^2*5^2 = 5*5*5*5*5*5*5*5

你不需要全部7次乘法,只需5*5、5^2*5^2、5^4*5^4(3次乘法)

以下代码是 Python 代码(因为我想轻松测试它),但我希望你明白这一点。

def powBase10(a,n):
    if(n==0):
        return 1
    x=powBase10(a, int(n/10))
    if(n%10==0):
        return (x*x*x*x*x*x*x*x*x*x)
    if(n%10==1):
        return (a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==2):
        return (a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==3):
        return (a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==4):
        return (a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==5):
        return (a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==6):
        return (a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==7):
        return (a*a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==8):
        return (a*a*a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==9):
        return (a*a*a*a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)

def powBase2(a,n):
    if(n==0):
        return 1
    x=powBase2(a, int(n/2))
    if(n%2==0):
        return (x*x)
    if(n%2==1):
        return (a*x*x)

使用基数 2 而不是基数 10 时,代码应该更快。 之所以要根据自己的基数调整算法是因为基数的除法可以通过删除最后一位来完成,所以除法不需要真正的计算。

对于这种方法,您需要的乘法数应该是对数而不是线性,所以几百位数应该没问题。

您可以使用相同的方法再次优化 base-10 代码

for example instead of:
x*x*x*x*x*x 
use:
y=x*x
y=y*y*y

但这只会导致持续的加速。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多