【问题标题】:Required: large number (max 1000 digits) stored in string modulo 11必需:以字符串模 11 存储的大数(最多 1000 位)
【发布时间】:2019-08-01 13:59:05
【问题描述】:

我有一个问题,就是求一个大数的模11。该数字存储在一个最大长度为 1000 的字符串中。我想用 C++ 对其进行编码。我该怎么办?

我尝试用 long long int 来做,但它不可能处理极端情况的值。

【问题讨论】:

  • 使用 GMP 库。
  • 十进制数 a_0+a_1*10+a_2*10^2+...+a_n*10^n 与 a_n-a_{n-1}+ 具有相同的余数模 11 a_{n-2}-....+(-1)^na_0。 1000 位数不适合 int 不是问题,因为后者的总和肯定适合。
  • 回复:“数字存储在字符串中...”——将数字存储在字符串中的方法有无数种。这里用的是哪一个?
  • 数字从字符串的位置0的最高位开始存储,最后一个位置的最低位开始

标签: c++ string modulo largenumber


【解决方案1】:

用十进制位置系统写为 a_na_{n-1}...a_0 是数字

a_n*10^n+a_{n-1}*10^{n-1}+...+a_0

首先注意这个数字和数字

a_0-a_{1}+a_{2}+...+(-1)^{n}a_n

这是它的带有交替符号的数字之和在除以 11 后具有相同的余数。您可以通过将两个数字相减并注意结果是 11 的倍数来检查。

基于此,如果给定一个由数字的十进制表示形式组成的字符串,则可以像这样计算余数模 11:

int remainder11(const std::string& s) {
  int result{0};
  bool even{true};
  for (int i = s.length() - 1; i > -1; --i) {
    result += (even ? 1 : -1) * ((int)(s[i] - '0'));
    even = !even;
  }
  return ((result % 11) + 11) % 11;
}

【讨论】:

  • 您的代码有两个问题。首先,您应该从最低有效位开始循环,因为 even 开头是 true(这可能会有所不同,但是,取决于您表示数字的方式,我假设是人类可读的格式)。其次,c++ 中的模运算符在用于负数时不会产生您想要的结果。例如-1 % 3 == -1。试试字符串"91",会破坏你的代码。也许你应该返回((result % 11) + 11) % 11
  • @KaenbyouRin 你是对的。我认为 C++ 已经纠正了这一点,但 Python 纠正了模数。
【解决方案2】:

好的,这是魔术(数学)技巧。

首先假设您有一个仅由1s 组成的十进制数。

比如说111111。很明显111111 % 110。 (因为您始终可以将其写为一系列11*10^n 的总和)。这可以推广到所有纯粹由偶数个整数组成的整数。 (例如11111111111111)。对于那些有奇数个的人,只需从中减去一个,您将得到一个 10 乘以一个由奇数组成的数字(例如 111=1+11*10),因此它们与 11 的模数将是 1 .

十进制数总是可以写成的形式

其中a0 是最低有效数字,an 是最高有效数字。注意10^n 可以写成10^n - 1 + 110^n - 1 是一个由n 组成的数字。如果n 是偶数,那么您将得到9 乘以偶数个偶数,并且它与11 的模始终是0。如果n 是奇数,那么我们得到9 乘以奇数个,它对11 的模总是9。不要忘记我们在10^n - 1 + 1 之后还有一个+1,所以我们需要将a 添加到结果中。

我们现在非常接近我们的结果:我们只需将所有内容相加,然后对11 进行最终模运算。伪代码如下:

Initialize sum to 0.
Initialize index to 0.
For every digit d from the least to most significant:
    If the index is even, sum += d
    Otherwise, sum += 10 * d
    ++index
    sum %= 11
Return sum % 11

【讨论】:

  • 请注意,添加10*d,与11*d - d 相同,与仅添加-d 相同,以便计算余数模11。这样做的好处是它保留了sum 稍微小一点,因此可以处理更大范围的输入而不会溢出。
  • @embeddedPy 只需添加一些代码来修改每个循环的结果。会使结果更小。
猜你喜欢
  • 1970-01-01
  • 2016-02-21
  • 1970-01-01
  • 2015-11-26
  • 2016-02-21
  • 2019-09-23
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多