【问题标题】:Add all the values between 100 and 4000000 inclusively that are divisable by 3 or 5 but not both 3 and 5将 100 到 4000000 之间的所有值相加,包括可被 3 或 5 整除但不能同时被 3 和 5 整除的值
【发布时间】:2015-11-16 05:21:32
【问题描述】:

将 100 到 4000000 之间的所有值相加,包括可被 3 或 5 整除但不能同时被 3 和 5 整除的值

无法弄清楚如何实施该规定的第二部分。这是我目前所拥有的:

var sum = 0;
for (var i = 100; i < 4000001; i++) {
    if (i % 3 || i % 5 === 0) {
        sum = sum + i;
    } 
}

【问题讨论】:

  • 这是什么语言?表达式i % 3 || i % 5 === 0 是什么意思?我觉得有点可疑。无论如何,假设你有A || B 正确,你真正需要的是“异或”,或“异或”:A &amp;&amp; !B || !A &amp;&amp; B
  • 我打错了。应该是 i % 3 === 0

标签: algorithm


【解决方案1】:

您可以使用sum of an arithmetic progression 的公式计算总和而无需任何循环:我们有

    3 + 5 + 6 + 9 + 10 + 12 + 18 + 20 + ...
=   3 + 6 + 9 + 12 + 15 + 18 + ...
  + 5 + 10 + 15 + 20 + ...
  - 2*(15 + 30 + 45 + ...)

请注意,我们将 3 和 5 的所有倍数相加,然后将 15 的倍数减去两次,因为它们被计算为 3 和 5 的倍数的两倍。

令 g(n) 为从 1 到 n 的整数之和。我们有g(n) = n*(n+1)/2

令 f(n) 为 1 和 n 之间可被 3 或 5 整除的整数之和,但不能同时被 5 整除。然后我们有

f(n) = 3*g(floor(n / 3)) + 5*g(floor(n/5)) - 30*g(floor(n/15))

m 和 n 之间可以被 3 或 5 整除但不能同时被 3 或 5 整除的整数之和就是 f(n) - f(m - 1)。这可以在 O(1) 中计算出来。

【讨论】:

  • (+1) 但我投票结束问题和答案,因为这整件事是关于数学而不是编程,属于另一个 stackexchange 网站。开个玩笑。
【解决方案2】:

您只需要转义那些涉及除以 15 的部分,其他更高的数字(15 的倍数)将被进一步自动避免。

请注意,通过15应在顶部的情况下检查可分配性,这是真实的,在不执行以下可分性的情况下,将继续进一步迭代3和5。如果是假的,则只能通过3或5或5即没有,但不是两者都有。

for (var i = 100; i < 4000001; i++) {
   if(i % 15 == 0 )
    continue;
   if (i % 3  == 0) {
    sum = sum + i;
   } 
   if (i % 5  == 0) {
    sum = sum + i;
   } 
}

另外,请注意您使用了=== 运算符,我认为它不是一个有效的运算符,您可能想要==。顺便说一句,我不确定是否有任何语言支持===,我认为 Javascript 支持。所以,在这一步要小心。

【讨论】:

    【解决方案3】:

    您可以使用!= 而不是||,因为这正是您想要的。只能被 3 或 5 整除,但不能同时被两者整除。

    var sum = 0;
    for (var i = 100; i < 4000001; i++) {
        if ((i % 3 == 0) != (i % 5 == 0)) {
            sum = sum + i;
        } 
    }
    

    【讨论】:

      【解决方案4】:
      var sum = 0;
      for (var i = 100; i < 4000001; i++) {
          if (i % 3 === 0 ^ i % 5 === 0) {
             sum = sum + i;
         } 
      }
      

      使用异或,异或^仅当其中一个条件不是两者都为真时才返回真。

      【讨论】:

      • 运算符^通常表示二进制异或,不是逻辑异或,不应与其他逻辑运算符混用。我不知道运算符 === 代表什么,所以要小心潜在的错误和未定义的行为。
      • Dialecticus ^ 表示异或,它是逻辑异而不是二进制异或,JavaScript 中的 === 也检查类型和值是否相等。只有当 i % 3 为 0 或 i % 5 等于 0 时才会通过。如果未定义,则不会
      • ^ 在什么语言中表示逻辑异或?在所有类 C 语言(C、C++、C#、Java、JavaScript)中,它是按位(二进制)异或。我提到了未定义的行为,因为^ 是按位异或,而=== 可能不会返回按位结果。
      • stackoverflow.com/questions/726652/… ^ 是并且也可以用作逻辑异或运算符或按位异或运算符。很简单,测试代码自己看看。
      • 他们谈论 Java。好吧,在 Java 中 ^ 是重载的,所以它也是逻辑异或。但是如果 OP 的代码语言不是 Java 怎么办?
      猜你喜欢
      • 2021-01-09
      • 2022-01-23
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2020-01-24
      相关资源
      最近更新 更多