简体   繁体   English

N 数的除数之和

[英]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 + 1n之间的所有数字的总和来获得一个等差数列。 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 * 1010 * 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.

相关问题 有效地找到一个数字的所有除数 - Efficiently finding all divisors of a number 给定数字是否为素数,如果不是 output 所有除数 - Is a given number a prime or not, if not output all its divisors 使用LINQ查找给定一系列素数的数的除数 - Find the number of divisors of a number given an array of prime factors using LINQ 根据从键盘输入的数字 n 求从 1 到 n 的奇数与偶数平方和的乘积 - Program to find the product of odd numbers from 1 to n and the sum of the squares of even numbers according to the number n entered from the keyboard Linq 查询以获取最多为 N 的所有数字(正数和负数),总和为数字 K - Linq query to get all numbers (positive and negative) up to N that sum up to number K 是否有一种已知算法可以找出 N 个元素中哪些 K 个元素的总和最接近整数? - Is there a known algorithm for finding which K elements out of N elements have a sum that is closest to a whole number? 在两个值之间获得n个不同的随机数,这两个值的总和等于给定的数字 - Get n distinct random numbers between two values whose sum is equal to a given number 用于查找大小为n的列表中的哪些数字与另一个数字相加的算法 - Algorithm to find which numbers from a list of size n sum to another number 最多的EPPlus总和 - Sum n largest numbers EPPlus 3SUM - O(n^2 * log n) 比 O(n^2) 慢? - 3SUM - O(n^2 * log n) slower than O(n^2)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM