项目欧拉问题1输出看似正确的代码时的问题

问题描述 投票:0回答:2

作为前言,我使用的是 Visual Studio 2022。Project Euler 上的问题指出:

如果我们列出 10 以下的所有自然数 是 3 的倍数 或 5,我们得到 3、5、6 和 9。这些倍数的总和是 23。求 1000 的所有倍数的总和 或者 下面。

几个小时后我自己完成了代码的大部分调试,但无法弄清楚这个小事情。我还问了一位自己解决了这个问题的朋友,在与她自己的工作代码进行比较后,她很困惑为什么它不正确。

这是我的代码:

int x = 0, y = 0, totalSum = 0;

//multiples of 3
for (int i = 0; x < 1000; i++)
{
    x = 3 * i;

    if (x % 5 != 0)
    {
        totalSum += x;
        Console.WriteLine(totalSum);
    }
}

//multiples of 5
for (int n = 0; y < 1000; n++)
{
    y = 5 * n;

    totalSum += y;
    Console.WriteLine(totalSum);
}

Console.WriteLine(totalSum);

Console.ReadKey();

运行时,控制台输出235,170。我揪着头发查了一下正确答案,我知道答案是233,168。我只是不知道如何到达那里。奇怪的是,当我将顶部

for
循环更改为 . 。 .

for (int i = 0; x < 996; i++)
{
    x = 3 * i;

    if (x % 5 != 0)
    {
        totalSum += x;
        Console.WriteLine(totalSum);
    }
}

。 。 。它输出 233,169。一关。我对发生的事情感到非常困惑。我对编程非常陌生——只在这里那里做了大约一个月,所以如果我的代码不是最优的,我深表歉意。感谢您的帮助,提前致谢!

c# output
2个回答
0
投票

首先恭喜你:用mod抓到15个案例干得好(

%
)!错误不在这里。

我相信错误在于

for (int i = 0; x < 1000; i++)

for (int n = 0; y < 1000; n++)

线。

你看,你可以想到 for 循环的形式

for(variable declaration; condition check; variable change) {
   body();
}

variable declaration;
while(condition check) {
   body();
   variable change;
}

在代码中,您使用

i
n
作为变量来跟踪迭代,但可以这么说,使用
x
y
作为
condition check
。这会导致这些循环再次运行。为什么?

问题是,考虑最后几个测试用例...... for 循环求和 3 秒何时停止?你会想到 999,因为 1002 大于 1000。然而,之后

Console.WriteLine(totalSum);

行,变量

i
将增加到334...但不会停止循环,因为
x
的值仍然是
999
。因此下面的
body()
将再次运行,
i
将增加到335,然后循环将停止为
1002 > 1000

注意:您可能可以通过查看其中某处的

Console.WriteLine("i: " + i + " x: " + x);
来捕获此错误。此问题通常称为“差一错误”。一般来说,需要通过打印或其他方式(也许在调试器中单步执行?)仔细检查循环的开始和结束来捕获这些。

虽然您可以在末尾添加另一个 if 语句,并使用类似的检查

if(x == 999) { break; }

这是多余的,并且实际上损害了代码的理解和可重用性。

一般来说,我会告诉您:作为初学者,不要在

condition check

中使用您声明的变量之外的其他变量。这可能会导致像我上面解释的那样的蠕动小错误(

off-by-one
错误)。

提示:您可以重构它以使用
i

作为

condition check
(也许这里可以使用整数除法?)或
x
,两者都需要一点重构。

话虽如此,作为一个初学者,我不想把答案告诉你!我希望上述建议,或许还有更多的批评,能够帮助您找到正确的解决方案。

快乐解决问题!


0
投票
编辑:我发现由于循环在开始时的检查方式,它会变成一倍。例如。 5
199 仍然小于 1000,因此循环继续进行并执行 5

200,超出了我认为设置的限制。我相应地改变了循环。我认为这比实际情况更复杂。感谢您的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.