0

所以我试图找到这个问题的答案:

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

我正在使用 C# 并且非常清楚该怎么做,但是我的代码一直在计算出现两次的数字(例如 15、30),我想知道最快/最简单的方法来抵消它。到目前为止,我发现的所有内容都使用不同的语言,所以如果这对您来说似乎相对容易,我很抱歉。这是我到目前为止所拥有的:

static void Main(string[] args)
    {
        var result1 = 0;
        var result2 = 0;
        var result3 = 0;
        var uniqueInts3 = new List<int>();
        for (var i = 0; i < 1000; i += 3)
        {
            uniqueInts3.Add(i);
            result1 += i;
        }
        var uniqueInts5 = new List<int>();
        for (var o = 0; o < 1000; o += 5)
        {
            uniqueInts5.Add(o);
            result2 += o;
        }
        result3 += result1 + result2;
        Console.WriteLine(result3);
        Console.ReadLine();
    }

如果有人可以向我解释该怎么做,我会很高兴,因为我现在不确定。

4

7 回答 7

6

不是最有效的方法,但应该有效

var sum = 0;

for(int i=0;i<1000;i++)
{
   if(i%3==0||i%5==0) //checks if something is multiple of 3 or 5
      sum+=i; // sums only when it's multiple of 3 or 5
}

它省略了某事物是 3 和 5 的倍数的情况。每个数字取一次。

一条线linq方式:

var sum = Enumerable.Range(3, 1000).Sum(x => (x % 3 == 0 || x % 5 == 0) ? x : 0);

最快的数学方法版本:

var result = SumDivisbleBy(3,999)+SumDivisbleBy(5,999)-SumDivisbleBy(15,999);

private int SumDivisbleBy(int n, int p)
{
    return n*(p/n)*((p/n)+1)/2;
}

它计算可被 3 和 5 整除的所有数字的总和,然后减去可被 15 整除的数字的总和。说明: http: //www.wikihow.com/Sum-the-Integers-from-1-to-N

于 2013-08-16T11:52:32.150 回答
5
var sum = Enumerable.Range(1, 1000)
          .Where(i => i % 3 == 0 || i % 5 == 0)
          .Sum();
于 2013-08-16T11:54:13.160 回答
3

只是为了提供一种替代方法...

首先,我们可以观察到 3 和 5 的倍数之间有间隔,重复顺序如下:

2, 1, 3, 1, 2, 3, 3

鉴于此,我们可以编写一个计算总数的方法,如下所示:

int sumMultiplesOf3And5UpTo(int n)
{
    int i = 3;
    int j = 0;
    int t = 0;

    int[] increments = new []{2, 1, 3, 1, 2, 3, 3};

    while (i <= n)
    {
        t += i;
        i += increments[j++%7];
    }

    return t;
}

为了获得终极速度,您可以像这样“展开增量数组”:

int sumMultiplesOf3And5UpTo(int n)
{
    int i = 3;
    int t = 0;

    while (true)
    {
        t += i;
        i += 2;
        if (i > n) break;

        t += i;
        i += 1;
        if (i > n) break;

        t += i;
        i += 3;
        if (i > n) break;

        t += i;
        i += 1;
        if (i > n) break;

        t += i;
        i += 2;
        if (i > n) break;

        t += i;
        i += 3;
        if (i > n) break;

        t += i;
        i += 3;
        if (i > n) break;
    }

    return t;
}

我永远不会像这样真正实现它;这只是一种好奇心(也是不同方法的一个例子)。

于 2013-08-16T12:21:52.883 回答
3

这是我的 2 美分

版本 1,使用 for 循环。

int sum = 0;
for(int i = 0; i < 10; i++)
    if (new[] {3, 5}.Any(n => i % n == 0)) 
        sum += i;

版本 2,使用 C# Linq

var sum =
    Enumerable.Range(1, 10 - 1)
       .Where(e => new[] { 3, 5 }.Any(n => e % n == 0))
       .Sum();

Enumerable.Range(1, 10 - 1)创建一个从 0 到 9(小于 10)的整数序列。

.Where(..)是一种过滤原始序列的方法。

new[] {3, 5}创建另一个仅包含 3 和 5 的序列。

.Any(n => e % n == 0)取 3 和 5 并对原始序列中的每个数字进行模运算。如果结果为 0,则该Any方法返回 true,这反过来意味着该Where方法在结果中包含该数字。

最后是总和。

于 2013-08-16T12:08:54.357 回答
2

一种简单的方法是循环从 1 到 1,000 的所有数字,看看它们是 3 还是 5 的倍数,如果是,只需将它们添加到result循环外的变量中。由于这是一个项目欧拉问题,我会让你自己计算代码。祝你好运!

PS,查看% 运算符,它会帮助你。

于 2013-08-16T11:53:35.823 回答
1

我玩了一点,这就是我的解决方案:

private static int sumMultiples(int max, int small, int big)
{
    int sum = 0;

    int diff_add = big - small;
    int diff = diff_add;
    int next = small;
    while (next < max)
    {
        sum += next;

        if (next + diff < max
            && (next + diff) % small != 0)
        {
            sum += next + diff;
        }
        diff += diff_add;

        next += small;
    }

    return sum;
}

while 循环运行最大/小次。

于 2013-08-16T13:25:37.097 回答
1

试试这个在 WriteLine() 之前得到结果

var sum = uniqueInts3.Concat(uniqueInts5).Distinct().Sum()

于 2013-08-16T11:53:48.717 回答