[英]Project Euler #23 in C# inefficient code execution time
我遍历了我的代码,并尝试使其尽可能有效。 我仍然无法在不冻结我的盒子的情况下让该程序一直运行。 我让它运行而不冻结的最大时间是大约2个小时。 我不敢相信这段时间没有执行。
是我的计算机出现问题还是这种解决该问题的蛮力方法效率低下。
在将来编写方法时,有哪些方法可以避免这种类型的效率低下?
private void Form1_Load(object sender, EventArgs e)
{
ArrayList listOfAbundantNumbers = new ArrayList();
ArrayList listOfSums = new ArrayList();
long total = 0;
for (int i = 1; i < 20162; i++)
{
if (isAbundandt(i))
{
listOfAbundantNumbers.Add(i);
}
total+=i;
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
for (int a = 0; a < listOfAbundantNumbers.Count; a++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
long temp2 = Convert.ToInt64(listOfAbundantNumbers[a]);
long num = temp1 + temp2;
if(listOfSums.Contains(num) == false)
{
listOfSums.Add(num);
}
}
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
total -= temp1;
}
printLn(total + "");
}
private ArrayList divisorList(long input)
{
ArrayList divisors = new ArrayList();
for (long i = 2; i < Math.Round(Math.Sqrt(input),0,0); i++)
{
long temp = input % i;
if (temp == 0)
{
divisors.Add(i);
divisors.Add(input / i);
}
}
return divisors;
}
private Boolean isAbundandt(long input)
{
long sum = 0;
ArrayList divisor = divisorList(input);
for (int i = 0; i < divisor.Count; i++)
{
long temp1 = Convert.ToInt64(divisor[i]);
sum += temp1;
}
sum++;
if (sum > input)
{
return true;
}
return false;
}
避免使用ArrayList
,最好使用通用集合,如List<Int64>
因为转换可能会非常昂贵。
您的程序中有一部分位于O(n ^ 3)中 。 可以很容易地减少到O(n ^ 2) 。 只需替换以下代码(由于List<T>.Contains
O(n)替换为:
if(listOfSums.Contains(num) == false)
{
listOfSums.Add(num);
}
通过:
listOfSums.Add(num);
其中listOfSums
现在是HashSet<Int64>
(它曾经有一个没有重复的集合)。
此外,只需注意如果交换i
和a
, sum
是相同的,那么就可以将填充listOfSums
的时间减少2倍,然后,仅将两个组合之一添加到listOfSums
。
您可以替换:
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a < listOfAbundantNumbers.Count; a++)
通过;
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a <= i; a++)
最终的代码是:
private static void Main()
{
List<Int64> listOfAbundantNumbers = new List<Int64>();
HashSet<Int64> listOfSums = new HashSet<Int64>();
long total = 0;
for (int i = 1; i < 20162; i++)
{
if (isAbundandt(i))
{
listOfAbundantNumbers.Add(i);
}
total += i;
}
for (int i = 0; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a <= i; a++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
long temp2 = Convert.ToInt64(listOfAbundantNumbers[a]);
long num = temp1 + temp2;
listOfSums.Add(num);
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
total -= temp1;
}
Console.WriteLine(total + "");
}
private static List<Int64> divisorList(long input)
{
List<Int64> divisors = new List<Int64>();
for (long i = 2; i < Math.Round(Math.Sqrt(input), 0, 0); i++)
{
long temp = input % i;
if (temp == 0)
{
divisors.Add(i);
divisors.Add(input / i);
}
}
return divisors;
}
private static Boolean isAbundandt(long input)
{
long sum = 0;
List<Int64> divisor = divisorList(input);
for (int i = 0; i < divisor.Count; i++)
{
long temp1 = divisor[i];
sum += temp1;
}
sum++;
if (sum > input)
{
return true;
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.