生成质数序列,Loop Break与LINQ TakeWhile

问题描述

我尝试用C#生成素数序列。 到目前为止,该代码似乎运行良好。

List<int> _primes = new List<int>();

bool IsPrime(int num)
{
    if (num < 2)
        return false;
    int chkEnd = (int)Math.Sqrt(num);

    foreach (var p in _primes)
    {
        if (p > chkEnd)
            break;
        if (num % p == 0)
            return false;
    }
    return true;
}

for (int i=2; i<1000000; i++)
{
    if (IsPrime(i))
        _primes.Add(i);
}

然后我将IsPrime()更改为使用LINQ TakeWhile(), 我认为这两种方法的时间复杂度相同, 但是执行时间明显长于前者。

bool IsPrime(int num)
{
    if (num < 2)
        return false;
    int chkEnd = (int)Math.Sqrt(num);

    foreach (var p in _primes.TakeWhile(x => x <= chkEnd))
    {
        if (num % p == 0)
            return false;
    }
    return true;
}

bool IsPrime(int num)
{
    if (num < 2)
        return false;
    int chkEnd = (int)Math.Sqrt(num);

    return _primes.TakeWhile(x => x <= chkEnd).All(p => num % p != 0);
}

有人有什么主意吗?


编辑: 我将循环迭代次数增加到5000000,在consoleApplication中运行代码并输出执行时间

00:00:01.1841593-IsPrime_PureLoopBreak

00:00:03.2560654-IsPrime_TakeWhileAndLoop

00:00:03.4178782-IsPrime_TakeWhileAndAll

    static void Main(string[] args)
    {
        List<int> _primes;

        bool IsPrime_PureLoopBreak(int num)
        {
            if (num < 2)
                return false;
            int chkEnd = (int)Math.Sqrt(num);

            foreach (var p in _primes)
            {
                if (p > chkEnd)
                    break;
                if (num % p == 0)
                    return false;
            }
            return true;
        }

        bool IsPrime_TakeWhileAndLoop(int num)
        {
            if (num < 2)
                return false;
            int chkEnd = (int)Math.Sqrt(num);

            foreach (var p in _primes.TakeWhile(x => x <= chkEnd))
            {
                if (num % p == 0)
                    return false;
            }
            return true;
        }

        bool IsPrime_TakeWhileAndAll(int num)
        {
            if (num < 2)
                return false;
            int chkEnd = (int)Math.Sqrt(num);

            return _primes.TakeWhile(x => x <= chkEnd).All(p => num % p != 0);
        }

        var t1 = Measure(() => 
        {
            _primes = new List<int>();
            for (int i = 2; i < 5000000; i++)
            {
                if (IsPrime_PureLoopBreak(i))
                    _primes.Add(i);
            }
        });
        Console.WriteLine($"{t1} -- IsPrime_PureLoopBreak");

        var t2 = Measure(() =>
        {
            _primes = new List<int>();
            for (int i = 2; i < 5000000; i++)
            {
                if (IsPrime_TakeWhileAndLoop(i))
                    _primes.Add(i);
            }
        });
        Console.WriteLine($"{t2} -- IsPrime_TakeWhileAndLoop");

        var t3 = Measure(() =>
        {
            _primes = new List<int>();
            for (int i = 2; i < 5000000; i++)
            {
                if (IsPrime_TakeWhileAndAll(i))
                    _primes.Add(i);
            }
        });
        Console.WriteLine($"{t3} -- IsPrime_TakeWhileAndAll");

        Console.ReadLine();
    }

    public static TimeSpan Measure(Action action)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        action?.Invoke();
        stopwatch.Stop();
        return stopwatch.Elapsed;
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)