问题描述
我尝试用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 (将#修改为@)