首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Euler退职计划

Euler退职计划
EN

Code Review用户
提问于 2015-01-28 00:04:44
回答 2查看 247关注 0票数 3

现在我正在做Euler 1项目:

如果我们列出所有低于10的自然数,它们是3或5的倍数,我们得到3,5,6和9。这些倍数之和是23。找出低于1000的3或5倍数之和。

这是我的代码,在0毫秒内运行:

代码语言:javascript
复制
static void Main(string[] args)
{
    Stopwatch s = new Stopwatch();
    s.Start();

    int sumNums = 0;

    for(int i = 0; i < 1000; i++)
    {
        if (i % 3 == 0 || i % 5 == 0) { sumNums += i; }
    }

    s.Stop();

    Console.WriteLine(sumNums);
    Console.WriteLine(s.ElapsedMilliseconds);
}

我也有这个版本,它也在0毫秒内运行。实际上,在同一个计时器中运行这两个方法会导致0毫秒的结果:

代码语言:javascript
复制
static void Main(string[] args)
{
    Stopwatch s = new Stopwatch();
    s.Start();

    int sumNums = 0;

    for (int i = 0; i < 1000; i += 3)
    {
        sumNums += i;
    }

    for (int i = 0; i < 1000; i += 5)
    {
        sumNums += i % 3 == 0 ? 0 : i;
    }

    s.Stop();

    Console.WriteLine(sumNums);
    Console.WriteLine(s.ElapsedMilliseconds);
}

什么可以改进,哪个版本更好?

EN

回答 2

Code Review用户

回答已采纳

发布于 2015-01-28 07:46:40

我没有C#编译器,但我认为如果您将i % 3放在第二个循环中,让它将所有倍数之和为5,然后再进行一次传递以删除15的倍数,那么第二个版本会更快。由于3、5、15的求和是重复的,所以我会引入一个助手函数,如下所示:

代码语言:javascript
复制
static int sumOfMultiples(int x, int limit)
{
    int sum = 0;
    for (int i = x; i < limit; i += x)
    {
        sum += i;
    }
    return sum;
}

然后在Main中,您可以写:

代码语言:javascript
复制
int max = 1000;
int sumNums = sumOfMultiples(3, max) + sumOfMultiples(5, max) - sumOfMultiples(15, max);

当然,@VikasGupta在评论中的建议是最好的,使用纯数学而不是循环,将助手重写为:

代码语言:javascript
复制
static int sumOfMultiples(int x, int limit)
{
    int n = (limit - 1) / x;
    return x * n * (n + 1) / 2;
}
票数 3
EN

Code Review用户

发布于 2015-01-28 00:40:16

由于我没有C#编译器(对不起),所以我将这两个程序转换为Java以进行测试。

第一代码:

平均速度: 80000- 90000纳秒

评论:

代码语言:javascript
复制
for(int i = 0; i < 1000; i++)
{
    if (i % 3 == 0 || i % 5 == 0) { sumNums += i; }
}

您可以在不影响结果的情况下安全地启动3

代码语言:javascript
复制
for(int i = 3; i < 1000; i++)
{
    if (i % 3 == 0 || i % 5 == 0) { sumNums += i; }
}

此外,您应该将if语句分成三行,以获得更好的可读性:

代码语言:javascript
复制
for(int i = 3; i < 1000; i++)
{
    if (i % 3 == 0 || i % 5 == 0) {
        sumNums += i;
    }
}

这个大概就是这个了。

第二代码:

平均速度: 60000 - 65000纳秒

评论:

代码语言:javascript
复制
for (int i = 0; i < 1000; i += 3)
{
    sumNums += i;
}

for (int i = 0; i < 1000; i += 5)
{
    sumNums += i % 3 == 0 ? 0 : i;
}

与以前一样,您可以从稍微大一点的数字开始:

代码语言:javascript
复制
for (int i = 3; i < 1000; i += 3)
{
    sumNums += i;
}

for (int i = 5; i < 1000; i += 5)
{
    sumNums += i % 3 == 0 ? 0 : i;
}

Thoughts

我认为两者在1000的时候都是相等的,但随着数字的增加,第一个数字会明显减慢。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/78825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档