繁体   English   中英

C#效率较低的代码执行时间中的Euler#23项目

[英]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> (它曾经有一个没有重复的集合)。

此外,只需注意如果交换iasum是相同的,那么就可以将填充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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM