所以我正在研究一个程序以分解给定的数字。您在命令行中输入一个数字,它将为您提供所有因素。现在,按顺序执行此操作非常慢。因为它只使用一个线程,如果我没有记错的话。现在,我考虑过使用Parallel.For
来做到这一点,并且它仅适用于整数,因此想尝试使用BigIntegers
以下是正常代码:
public static void Factor(BigInteger f)
{
for(BigInteger i = 1; i <= f; i++)
{
if (f % i == 0)
{
Console.WriteLine("{0} is a factor of {1}", i, f);
}
}
}
上面的代码应该很容易理解。但是就像我说的那样,这对于大数字来说非常慢(超过十亿,它开始变得不切实际),这是我的并行代码:
public static void ParallelFacotr(BigInteger d)
{
Parallel.For<BigInteger>(0, d, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, i =>
{
try
{
if (d % i == 0)
{
Console.WriteLine("{0} is a factor of {1}", i, d);
}
}
catch (DivideByZeroException)
{
Console.WriteLine("Done!");
Console.ReadKey();
Launcher.Main();
}
});
}
现在,以上代码(并行代码)对整数(int)正常工作,但非常快。它在短短2秒钟内分解了1000.000.000。所以我想为什么不尝试使用更大的整数呢。而且,我认为可以将<Biginteger>
放在parallel.for
之后。但事实并非如此。那么,如何与bigintegers并行进行循环工作?而且我已经尝试过使用bigInteger作为参数的常规并行循环,但是随后出现错误,表明它无法从BigInteger转换为int。那你怎么样
答案 0 :(得分:1)
首先提高算法效率。
虽然可以使用BigInteger,但是您将没有CPU ALU算术逻辑来解析硬件中的任意大数逻辑,因此它的运行速度会明显变慢。因此,除非您需要的数字大于9位数或正好 9,223,372,036,854,775,807 ,否则您可以使用类型long
。
第二件事是,您不需要遍历所有元素,因为它需要多个元素,因此可以减少
for(BigInteger i = 1; i <= f; i++)
for(long i = 1; i <= Math.Sqrt(f); i++)
这意味着您无需迭代超过1000000000项,而可以迭代31623。
应该是
的一行Parallel.For(
0,
(int)d,
() => BigInteger.Zero,
(x, state, subTotal) => subTotal + BigInteger.One,
只是琐事。某些编程语言比其他编程语言更有效地解决问题,并且在这种情况下,只要您知道自己在做什么,就可以使用解决问题更简单的Wolfram语言(以前称为Mathematica)。
但是他们确实有Google替代品可以直接回答您,并且它还具有不错的AI,可以处理您的自然语言,从而为您提供尽可能最佳的准确答案。
因此,找到数字因素很容易,因为:
Factor[9223372036854775809]
或使用网络API https://www.wolframalpha.com/input/?i=factor+9223372036854775809
您还可以从C#调用Wolfram内核,但必须遵守条款和条件。