[英]The sum of the divisors of an N number
Find then sum all the divisors from 1 to N.找到然后求和从 1 到 N 的所有除数。
The main problem is, that this code runs really poor with high numbers.主要问题是,此代码在高数字下运行非常糟糕。
The following code was taken from: https://www.geeksforgeeks.org/sum-divisors-1-n以下代码取自: https : //www.geeksforgeeks.org/sum-divisors-1-n
static int divisorSum(int n)
{
int sum = 0;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j * j <= i; ++j)
{
if (i % j == 0)
{
if (i / j == j)
sum += j;
else
sum += j + i / j;
}
}
}
return sum;
}
Based on @Joel solution, I just improved it:基于@Joel 解决方案,我只是对其进行了改进:
static long divisorSum(int n)
{
long sum = 0;
for (long i = 1; i <= n/2; ++i)
sum += i * (n / i);
sum += (n/2+1+n)*(n-n/2)/2; // It's a sum of an arithmetic progression
return sum;
}
For i
> n/2
the expression i * (n / i)
is simply i
(because n/i
= 1), so we can get the sum of all the numbers between n/2 + 1
to n
by computing a sum of an arithmetic progression.对于i
> n/2
,表达式i * (n / i)
就是简单的i
(因为n/i
= 1),所以我们可以通过计算n/2 + 1
到n
之间的所有数字的总和来获得一个等差数列。 It will run faster, although it is O(n)
too.它会运行得更快,尽管它也是O(n)
。
There is no need to use a collection of sorts, since you sum everything up and don't need to think about duplicates.无需使用各种集合,因为您将所有内容汇总在一起,无需考虑重复项。 I don't think there is a way to get a solution for this which is a perfect O(n)
, but this is the closest I can think of:我不认为有办法解决这个问题,这是一个完美的O(n)
,但这是我能想到的最接近的:
int sum = 0;
for (int i = 1; i <= n; i++)
{
double sqrt = Math.Sqrt (i);
for (int j = 1; j <= sqrt; j++)
{
if (i % j == 0)
{
sum += j;
if (j != sqrt)
sum += i / j;
}
}
}
Divisors are pairs, so there isn't a need to go all the way to i
every time (eg 1 * 10
, 10 * 1
are the same).除数是成对的,所以不需要每次都一直到i
(例如1 * 10
、 10 * 1
是相同的)。 You can go till the square-root of i
(the 'mid-point'), and save time, hence it's not O(n^2)
, but not perfectly O(n)
.您可以计算i
的平方根(“中点”),并节省时间,因此它不是O(n^2)
,但也不是完美的O(n)
。
You could do something like this O(n)
:你可以做这样的事情O(n)
:
static long divisorSum(int n)
{
long sum = 0;
for (long i = 1; i <= n; ++i)
sum += i * (n / i);
return sum;
}
static void Main(string[] args)
{
int val = 129999;
Console.WriteLine(divisorSum(val));
Console.ReadLine();
}
Tests:测试:
12999 => 8ms
129999 => 25ms
2147483647 => 18770ms (Max Int32 value)
int val = 129999;
int maxInt = int.MaxValue;
//val (129999)
var watch = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine(divisorSum(val));
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine(elapsedMs); //25ms
//MaxInt (2147483647)
watch = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine(divisorSum(maxInt));
watch.Stop();
elapsedMs = watch.ElapsedMilliseconds; //18770ms
Console.WriteLine(elapsedMs);
Console.ReadLine();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.