【问题标题】:b%a where b is very large [closed]b%a 其中 b 非常大 [关闭]
【发布时间】:2015-04-07 10:34:49
【问题描述】:

我们得到两个整数aba <= 100000b < 10^250。我想计算b%a。我找到了这个算法,但不知道它是如何工作的。

int mod(int a, char b[])
{
    int r = 0;
    int i;
    for(i=0;b[i];++i)
    {
      r=10*r +(b[i] - 48);
      r = r % a;
    }
    return r;
}

请解释这背后的逻辑。我知道模数学的基本性质。

谢谢。

【问题讨论】:

  • 这里唯一的幻数是48。它是符号“0”的ASCII码。所以"0" - 48 == 0;"1" - 48 == 1; 等等。其余的代码由你来理解。
  • @MarkGraph 你的讽刺比你猜的要好。
  • 你“找到”的那段代码不带“两个整数,a 和 b”,所以这不是一个很好的开始。
  • @DanielDaranas 我写道,我们有两个整数。我没有说我是如何输入的。在这种情况下,很明显,较大的数字 b 作为字符串输入。
  • 他不应该投反对票。他忘了解释 iof b 的值是如何输入的,并假设你反对的人会理解它。这是他唯一搞错的地方。他关于此函数如何计算模 的问题很有趣,并且很容易与高效计算多项式的方式相关联。 Horner's Algorithm

标签: c++ modulus largenumber


【解决方案1】:

很容易弄清楚您是否知道模运算,表达式(b[n] + 10 * b[n - 1] + ... + 10^k * b[k] + ... + 10^n * b[0]) modulo a(从技术上讲是初始问题陈述)可以简化为(...((b[0] modulo a) * 10 + b[1]) modulo a) * 10 + ... + b[n]) modulo a,这就是您的算法所做的。

为了证明它们相等,我们可以在第二个表达式中在 b[i] 之前计算系数模 a,很容易看出对于 b[i] 将恰好有 n - i 次,我们必须将它乘以10(最后一个 n 将乘以 0 倍,他之前的一个将乘以 1 倍,依此类推......)。所以对a 取模等于10 ^ (n - i),这与第一个表达式中b[i] 之前的系数相同。

因此,由于两个表达式中b[i] 之前的所有系数都相等,很明显两个表达式都等于(k_0 * b[0] + k_1 * b[1] ... + k_n * b[n])a,因此它们模等于a

480 数字的字符代码,所以(b[i] - 48) 是从字符到数字的转换。

【讨论】:

  • 我不明白它是如何被简化为 (...((b[0] modulo a) * 10 + b[1]) modulo a) * 10 + ... + b[n]) 模 a
  • @AbhilashSingh 要在b[i] 之前计算系数,您必须将10 modulo an - i 括号相乘,这与第一个表达式中的(10^(n - i)) modulo a 相同。
【解决方案2】:

基本上这个函数实现Horner's Algorithm来计算b的十进制值。

正如@Predelnik 解释的那样,b 的值是一个多项式,其系数是b 的数字,变量x10。该函数使用模与加法和乘法兼容的事实计算每次迭代的模数:

(a+b) % c = ((a%c) + (b%c)) % c
(a*b) % c = ((a%c) * (b%c)) % c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 2020-12-25
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多