[英]Sum of numbers under 10,000 that are multiples of 3, 5 or 7 in Java
I know how to get the program to add up the sums of the multiple for each of 3, 5 and 7, but I'm not sure how I'd get the program to only use each number once. 我知道如何让程序为3,5和7中的每一个加总多个的总和,但我不确定如何让程序只使用每个数字一次。 For example, I can get the program to find out all of the numbers and add them up for 3 and then do the same for 5, but then the number 15 would be in the final number twice.
例如,我可以让程序找出所有数字并将它们加起来为3然后对5进行相同的操作,但是数字15将在最终数字中两次。 I'm not sure exactly how I'd get it to only take the number once.
我不确定我是怎么得到它只采取一次数字。 Thanks for any help.
谢谢你的帮助。
While the generate-and-test approach is simple to understand, it is also not very efficient if you want to run this on larger numbers. 虽然生成和测试方法很容易理解,但如果你想在更大的数字上运行它也不是很有效。 Instead, we can use the inclusion-exclusion principle .
相反,我们可以使用包含 - 排除原则 。
The idea is to first sum up too many numbers by looking at the multiples of 3, 5 and 7 separately. 我们的想法是首先通过分别查看3,5和7的倍数来总结太多数字。 Then we subtract the ones we counted twice, ie multiples of 3*5, 3*7 and 5*7.
然后我们减去我们计算两次的数,即3 * 5,3 * 7和5 * 7的倍数。 But now we subtracted too much and need to add back the multiples of 3*5*7 again.
但现在我们减去了太多,需要再次加回3 * 5 * 7的倍数。
We start by finding the sum of all integers 1..n
which are multiples of k
. 我们首先找到所有整数
1..n
的总和,它是k
倍数。 First, we find out how many there are, m = n / k
, rounded down thanks to integer division. 首先,我们通过整数除法找出有多少,
m = n / k
,向下舍入。 Now we just need to sum up the sequence k + 2*k + 3*k + ... + m*k
. 现在我们只需要总结序列
k + 2*k + 3*k + ... + m*k
。 We factor out the k
and get k * (1 + 2 + ... + m)
. 我们将
k
分解出来并得到k * (1 + 2 + ... + m)
。
This is a well-known arithmetic series, which we know sums to k * m * (m + 1)/2
(See triangle number ). 这是一个众所周知的算术系列,我们知道总和为
k * m * (m + 1)/2
(见三角形数 )。
private long n = 9999;
private long multiples(long k) {
long m = n / k;
return k * m * (m + 1) / 2:
}
Now we just use inclusion-exclusion to get the final sum: 现在我们只使用包含 - 排除来获得最终总和:
long sum = multiples(3) + multiples(5) + multiples(7)
- multiples(3*5) - multiples(3*7) - multiples(5*7)
+ multiples(3*5*7);
This will scale much better to larger n
than just looping over all the values, but beware of overflow and change to BigInteger
s if necessary. 这将扩展到更大的
n
而不仅仅是循环所有值,但要注意溢出并在必要时更改为BigInteger
。
The easiest approach would be to use a for
loop thus: 最简单的方法是使用
for
循环:
int sum = 0;
for(int i=1; i<10000; i++)
{
if (i % 3 == 0 || i % 5 == 0 || i % 7 == 0)
sum += i;
}
使用Set存储唯一的倍数,然后对Set的值求和。
One simple solution would be to add each number thats a multiple of 3,5, or 7 to an Answer list. 一个简单的解决方案是将每个数字(3,5或7的倍数)添加到答案列表中。 And then as you work thru each number, make sure that its not already in the answer list.
然后当您通过每个号码工作时,请确保它不在答案列表中。
(pseudo-code) (伪代码)
List<int> AnswerList;
List<int> MultiplesOfFive;
List<int> MultiplesOfSeven;
List<int> MultiplesOfThree;
for (int i = 0 ; i < 10000; i++)
{
if ( i % 3 == 0 && AnswserList.Contains(i) == false)
{
MultiplesOfThree.Add(i);
AnswerList.Add(i);
}
if ( i % 5 == 0 && AnswserList.Contains(i) == false)
{
MultiplesOfFive.Add(i);
AnswerList.Add(i);
}
if ( i % 7 == 0 && AnswserList.Contains(i) == false)
{
MultiplesOfSeven.Add(i);
AnswerList.Add(i);
}
}
对于循环1到1000使用i <= 10000的解决方案,否则它将跳过10000本身,这是5的倍数。道歉,由于某种原因我不能发布这个作为评论
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.