如何优化这个c#代码?

时间:2017-11-08 22:35:45

标签: c# arrays primes object-reference

我在编程平台上遇到了挑战(CodeWars - “查找除数”),我的算法似乎太慢了。 这是我从平台得到的错误:进程已终止。完成时间超过12000毫秒

这是挑战说明 创建一个名为divisors / Divisors的函数,它接受一个整数并返回一个包含所有整数除数的数组(除1和数字本身除外)。如果数字是素数返回字符串'(整数)是素数'(C#中为null)

public static int[] Divisors(int n /* out int numfactors*/)
{
    List<int> divArray = new List<int>(); 
    int div;

    if (isPrime(n))
    {
        return divArray.ToArray();
    }
    else
    {

        for (div = 2; div < n / 2 + 1; div++)
        {
            if (n % div == 0)
            {
                divArray.Add(div);
            }

            return divArray.ToArray();
        }
    }
}

public static bool isPrime(int n)
{
    int d = 2;

    if (n == 1 && n % 2 == 0 && n != 2) return false;

    while (d * d <= n)
    {
        if (n % d == 0) return false;

        d = d + 1;
    }

    return true;
}

我做错了什么,我怎么能优化这个算法?如果我测试素数,我的代码返回“没有”,我认为这是另一个问题。 如果数字是素数,并且我正在尝试返回null 我的程序崩溃: “对象引用未设置为对象的实例”

1 个答案:

答案 0 :(得分:0)

在对您的问题的评论中,其他人已经注意到您的程序在您担心性能之前需要解决的正确性问题,并且这绝对是正确的。但是,由于您询问了性能,请考虑while中的IsPrime循环和for中的Divisors循环都基本上做同样的事情:迭代一组潜在因素并确定它们是否均匀划分n。所以:

  1. 你为什么两次这样做?由于在复合n的情况下需要生成完整的因子列表,为什么不直接生成整个列表,然后根据列表的大小推断n是否为素数?

  2. 更重要的是,当for中的Divisors循环正确观察时,为什么n/2+1 while循环使用IsPrime作为其上限你真的需要去√n吗?是的,复合n的因子大于√n,但您不需要在该点之上迭代才能找到它们,因为任何k均匀分割n,您知道n/k也会平均分割n