【问题标题】:Reconstructing a list of divisors from the prime factors (recursively)从主要因素重建除数列表(递归)
【发布时间】:2013-10-25 02:52:11
【问题描述】:

我有一个数字的质因数列表,格式如下: int[] 因子 = {因子数,factor1,poweroffactor1,factor2,poweroffactor2,...};

我想获得等效的动态嵌套 for 循环,它将产生所有因素,其中 for 循环看起来像这样:

int currentpod = 1;
for(int i=0;i<factors[2];i++)
{
    currentprod *= Math.Pow(factors[1],i);
    for(int j=0;j<factors[4];j++)
    {
         currentprod *= Math.Pow(factors[3],i);
         ...
         //When it hits the last level (i.e. the last prime in the list, it writes it to a list of divisors
         for(int k=0;k<factors[6];k++)
         {
              divisors.Add(Math.Pow(factors[5],k)*currentprod);
         }
    }
}

不幸的是,由于 currentprod 没有得到足够的重置,这段代码会崩溃。 这是我用来尝试完成此操作的实际代码:

        public static List<int> createdivisorlist(int level, List<int> factors, int[] prodsofar,List<int> listsofar)
    {
        if (level == factors[0])
        {
            prodsofar[0] = 1;
        }
        if (level > 1)
        {
            for (int i = 0; i <= 2*(factors[0]-level)+1; i++)
            {
                prodsofar[level-1] = prodsofar[level] * (int)Math.Pow(factors[2 * (factors[0] - level) + 1], i);
                listsofar =  createdivisorlist(level - 1, factors, prodsofar, listsofar);
            }
        }
        else
        {
            for (int i = 0; i <= factors.Last(); i++)
            {
                listsofar.Add(prodsofar[level] * (int)Math.Pow(factors[2 * (factors[0] - level) + 1], i));
                if (listsofar.Last() < 0)
                {
                    int p = 0;
                }
            }
            return listsofar;
        }
        return listsofar;
    }

原来的论点是: 水平=因素[0] 因子 = 上面指定格式的主要因子列表 prodsofar[] = 所有元素都是 1 listofar = 一个空列表

如何重置 prodsofar 以使其不会“爆炸”而只是按照我的概述进行操作? 注意:作为测试,使用2310,在当前代码下,要添加的除数为负(int溢出)。

【问题讨论】:

  • 这看起来不必要地复杂。 prodsofarlistsofar 应该代表什么?
  • 当前乘积(要传递给函数的下一个实例以便它可以相乘),listofar 是除数列表。
  • 我知道 c++,但不知道 c#。即便如此,我还是看到了一些看起来像错误的东西。循环限制看起来不对,prodsofar 可以是int,而不是int[],您可以使用*= 并取消Pow。在尝试 2310 之前,您是否尝试过在 2 上运行它?

标签: c# math recursion prime-factoring


【解决方案1】:

您想到的递归算法的想法是保留一个累积的除数列表。为此,下面的代码是如何做到这一点的示例(保留您的符号:由于“除数”和“因子”的含义完全相同,因此多个术语是不幸的):

public static List<int> divisors(int[] factors, List<int> foundfactors, int level)
{
    if(level > factors[0]) return foundfactors;

    int current = 1;
    List<int> curpowers = new List<int>();
    for(int i=0; i<factors[2*level]+1; ++i)
    {
        curpowers.Add(current);
        current *= factors[2*level-1];
    }
    List<int> newfactors = new List<int>();
    foreach(int d in foundfactors)
        foreach(int n in curpowers)
            newfactors.Add(d*n);
    return divisors(factors, newfactors, level + 1);
}

用类似的东西调用它

    // 600 = 2^3 * 3^1 * 5^2
    int[] pfactors = new int[] {3, 2,3, 3,1, 5,2};
    List<int> foundfactors = new List<int> {1};
    List<int> ds = divisors(pfactors, foundfactors, 1);
    foreach(int d in ds) Console.WriteLine(d);

打印 600 的所有 24 个除数。

【讨论】:

    【解决方案2】:

    这只是一个“生成所有组合”的问题。您可以使用您最喜欢的搜索引擎在 C# 中找到执行此操作的方法; here 就是一个例子。

    请注意,您需要将“prime p used k times”映射到{p, p, p, ...}(k 次)。

    【讨论】:

    • 我的意思是我可以那样做,但实际上,我只想要所有产品,而且如果我将其作为组合问题来做,我会产生额外的开销。
    • 您是否可以编写一个示例,说明使用您向我发送链接的库的外观?
    • 此外,它无法处理重复组合,这是我需要的关键部分。
    【解决方案3】:

    这类似于接受的答案 - 对于试图了解发生了什么的人来说可能更清楚......

    def divisors_from_primes(primes, v = 1)
      if primes.empty?
        puts v
        return
      end
      p = primes.keys.first
      m = primes[p]
      primes.delete(p)
      0.upto(m) do |power|
        divisors_from_primes(primes, v * (p**power))
      end  
      primes[p] = m
    end
    
    /* 72 = 2**3 * 3**2  */
    
    divisors_from_primes({ 2 => 3, 3 => 2})
    

    所以在这个例子 (72) 中,它基本上是一个递归版本:

    0.upto(3) do |twopower|
      0.upto(2) |threepower|
        puts 2**twopower * 3**threepower
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 2018-09-30
      • 2011-10-26
      • 2012-08-23
      • 2016-05-04
      相关资源
      最近更新 更多