这是示例代码
public static decimal factorization(decimal num, decimal factor)
{
if (num == 1)
{
return 1;
}
if ((num % factor)!= 0)
{
while(num% factor != 0)
{
factor++;
}
}
factors.Add(factorization(num / factor, factor));
return factor;
}
注意:我将因素初始化为全局因素。
以上代码适用于样本输入90,18991325453139但不适用于输入12745267386521023 ...所以我该怎么做?我怎样才能有效地实现这一点...我知道递归调用将消耗内存,这就是为什么我在没有递归的情况下检查了最后一个输入的原因..但是它不能正常工作
答案 0 :(得分:3)
如果
,您可以使用它factor*factor > num
然后num是素数
它会降低从O(n)
到O(sqrt(n))
修改强>
while(num% factor != 0)
{
factor++;
if(factor*factor>num){ // You can precalc sqrt(num) if use big arifmetic
factor=num; //skip factors between sqrt(num) and num;
}
}
答案 1 :(得分:3)
using System.Collections;
public static int[] PrimeFactors(int num)
{
ArrayList factors = new ArrayList();
bool alreadyCounted = false;
while (num % 2 == 0)
{
if (alreadyCounted == false)
{
factors.Add(2);
alreadyCounted = true;
}
num = num / 2;
}
int divisor = 3;
alreadyCounted = false;
while (divisor <= num)
{
if (num % divisor == 0)
{
if (alreadyCounted == false)
{
factors.Add(divisor);
alreadyCounted = true;
}
num = num / divisor;
}
else
{
alreadyCounted = false;
divisor += 2;
}
}
int[] returnFactors = (int[])factors.ToArray(typeof(int));
return returnFactors;
}
我刚刚复制并发布了Smokey Cogs的一些代码,因为这是一个非常常见的问题。
代码比你的更好。
首先除以2,直到数字不再均匀。从那里开始,你可以从3开始,然后按2递增(跳过每个偶数),因为所有的2都被分解了。
尽管如此,仍有一些方法可以改进。考虑一下代码中“alreadyCounted”的用法。这绝对必要吗?例如,使用
if (num % 2 == 0)
{
factors.Add(2);
num = num/2;
}
while( num %2 == 0)
{num = num/2;}
允许您在开头跳过额外的比较。
RiaD也提供了一个很好的启发式,factor^2 > num
暗示num是素数。这是因为(sqrt(n))^2 = n
,因此,sqrt(n)
除num
之后唯一的数字将是num
本身,一旦您取出之前的素数。
希望它有所帮助!
答案 2 :(得分:1)
要了解如何在C#中查找给定数字的因子,请参阅this (duplicate?) StackOverflow question。
您的代码中的几点:
yield
)。uint
或ulong
)而不是decimal
,因为您正在使用整数。对于任意大整数,请使用System.Numerics.BigInteger
。另外,请注意,没有已知的有效算法来分析大数字(有关简要概述,请参阅Wikipedia)。
这是基于上述观察的示例代码:
static IList<BigInteger> GetFactors(BigInteger n)
{
List<BigInteger> factors = new List<BigInteger>();
BigInteger x = 2;
while (x <= n)
{
if (n % x == 0)
{
factors.Add(x);
n = n / x;
}
else
{
x++;
if (x * x >= n)
{
factors.Add(n);
break;
}
}
}
return factors;
}
请注意,这仍然是一个相当天真的算法,可以很容易地进一步改进。