【问题标题】:Fastest way to find sum of digits on big numbers在大数上找到数字总和的最快方法
【发布时间】:2010-04-15 20:35:45
【问题描述】:

我有一些大数字(再次),我需要找出数字的总和是否为偶数。 我试过这个:用while循环找到数字的总和,然后检查sum % 2 是否等于0并且它正在工作,但是对于大数字来说太慢了,因为我得到了数字的间隔,如果输入是1999999 19999999999 那么我的程序失败了,我无法在 0.1 秒的时间限制内完成。

怎么办?有没有其他更快的方法来做到这一点?

编辑:输入 1999999 19999999999 意味着它将以 1999999 开头并检查我上面写的所有数字,直到 19999999999,因为我们谈论的是大数字(

【问题讨论】:

  • 如果你被要求在 0.1 秒内输出近 200 亿次“是”或“否”,你还不如现在就放弃。仅输出答案会超出时间限制。
  • 您不需要整数就知道总和是否偶数。你只需要每个的最后一个数字
  • Hogan:你能告诉我那个公式叫什么吗?
  • @dada:我想对数字而不是数字求和。
  • @dada: 这是用什么语言写的,适用于什么班级?

标签: c++ while-loop


【解决方案1】:

您不需要对数字求和。想想看。总和从零开始,通常被认为是偶数(尽管您可以根据需要对此进行特殊处理)。

每个偶数都不会改变。如果总和是奇数,则保持奇数,如果是偶数,则保持偶数。

每个奇数将总和从偶数变为奇数,或将奇数变为偶数。

所以,只计算奇数位数。如果数字是偶数,那么所有数字的总和是偶数。如果数字是奇数,那么所有数字的和都是奇数。

现在,您只需为您范围内的第一个数字执行此操作。接下来你需要做的是弄清楚当你不断添加一个数字时,数字的奇偶性是如何变化的。

我将此作为练习留给读者。家庭作业必须涉及一些工作!

【讨论】:

  • 有趣的是,我们俩同时写了相同的“提示”。
  • 您甚至不必对奇数位数求和(伪代码): sum_is_odd = false; foreach(digit) { sum_is_odd ^= (digit & 1); }
  • 是的,为了更快的工作,不要费心提取最后一位直到结束: sum_is_odd = 0; foreach(数字) { sum_is_odd ^= 数字; } sum_is_odd &= 1;
【解决方案2】:

提示:如果你发现给定数n的位数和是奇数,那么数n + 1的位数和是奇数还是偶数?

更新: 正如@Mark 指出的那样,它并不是那么 简单......但是只有当n + 1 是10 的倍数时才会出现异常,即@ 987654324@。然后奇怪的东西没有改变。然而,在这些情况下,每 10 次是一个例外,当奇数确实发生变化时(例如 199 -> 200)。依此类推……基本上,根据n 的最高值9 的位置,可以确定nn + 1 之间的奇数是否变化。我承认计算起来有点乏味,但我仍然相信它比将所有这些数字相加要快...

【讨论】:

  • 7:奇数,8:偶数,9:奇数,10:奇数
  • 不是每十个 - 看看我和 swestrup 的答案,如果奇数位数发生变化,只有每 10 个。 (例如 99->100 偶数 -> 奇数)
  • @Hogan 这就是我试图表达的意思(我承认你和@swestrup 解释得更清楚)。
【解决方案3】:

这是一个提示,它可能会起作用 - 您不需要将数字相加,您只需要知道结果是奇数还是偶数 - 如果您从假设您的总数是偶数,偶数开始没有效果,奇数切换(即奇数的奇数使其成为奇数)。

根据语言的不同,可能有更快的方法来执行计算而无需添加。

还要记住——一个数字是奇数还是偶数取决于它的最后一个二进制数字。

例子:

在 ASM 中,您可以对低位进行异或运算以获得正确的结果

在 FORTH 中这不会很好地工作......

【讨论】:

  • 这是一个很好的提示,但最初的提问者只需要在最小的数字上做一次那部分......然后使用上面的建议。
  • 它需要在至少是 10 的幂的每次更改中执行此操作 - 计算出 10 的幂并不容易 - 需要一些缓慢的 IF 语句。 XOR 很快。 (尤其是如果你在内存中布置好数据。)
猜你喜欢
  • 1970-01-01
  • 2021-12-19
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多