分解最大数量

时间:2011-07-31 12:33:10

标签: c# algorithm factors

这是示例代码

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 ...所以我该怎么做?我怎样才能有效地实现这一点...我知道递归调用将消耗内存,这就是为什么我在没有递归的情况下检查了最后一个输入的原因..但是它不能正常工作

3 个答案:

答案 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)。
  • 你的第二个if语句是多余的,因为它包含了一个具有相同条件的while循环。
  • 您应该使用整数类型(并且无符号整数类型将允许比其签名对应项更大的数字,例如uintulong)而不是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;
}

请注意,这仍然是一个相当天真的算法,可以很容易地进一步改进。