【问题标题】:recursive Permutation of a 3 Digit Number3位数字的递归排列
【发布时间】:2014-04-20 18:09:15
【问题描述】:

我正在研究递归查找 3 位数字的所有排列。

我已经厌倦了以下排列方法:

    static int a = 1;
    static int b = 2;
    static int c = 3;
    static int aCount;
    static int bCount;
    static int cCount;

    static void perm(int a, int b, int c)
    {

        Console.WriteLine("( {0}, {1}, {2} )", a, b, c); // (1,2,3 )

        if (aCount < 1 && bCount<1 &&cCount<1)
        {
            aCount++;

            perm(a, c, b);
        }
        else
            if (aCount==1 && bCount < 1 && cCount<1)
            {

                bCount++;
                perm(b, a, c);
            }
            else
                if (aCount == 1 && bCount == 1 && cCount < 1)
                 {
                    perm(b,c,a);
                  }
        else
                if (aCount==1 && bCount==1 && cCount < 1)
                {
                    cCount++;
                    perm(c, a, b);  //c b a

                }
               else
                    if (aCount == 1 && bCount == 1 &&  cCount == 1)
                {
                    perm(c, b, a);

                }

            }

我试图涵盖所有案例,每个步骤都有详细信息,但我仍然突然收到堆栈溢出异常。

感谢您的贡献,感谢转发。

【问题讨论】:

  • 请在开始前将aCount、bCount和cCount初始化为0。
  • 哦,抱歉,我一定是在实验时错过了这个:P

标签: c# algorithm recursion backtracking recursive-backtracking


【解决方案1】:

您是说您正在尝试递归,但所有这些行都出现在您的代码中:

perm(a, c, b)
perm(b, a, c)
perm(b, c, a)
perm(c, a, b)
perm(c, b, a)

当然还有函数的第一次调用:perm(a, b, c)

这样做更容易:

static void perm(int a, int b, int c)
{
    Console.WriteLine("( {0}, {1}, {2} )", a, b, c);
    Console.WriteLine("( {0}, {2}, {1} )", a, b, c);
    Console.WriteLine("( {1}, {0}, {2} )", a, b, c);
    Console.WriteLine("( {1}, {2}, {0} )", a, b, c);
    Console.WriteLine("( {2}, {0}, {1} )", a, b, c);
    Console.WriteLine("( {2}, {1}, {0} )", a, b, c);
}

【讨论】:

  • 我希望是这样的!我被要求写一个 RECURSIVE 置换函数,只有:S
  • 我需要一种递归方式来打印每个排列的行。
【解决方案2】:

一方面,这两种情况中的任何一种都会导致无限递归:

if (aCount == 1 && bCount == 1 && cCount < 1)
{
    perm(b,c,a);
}

还有:

if (aCount == 1 && bCount == 1 && cCount == 1)
{
    perm(c, b, a);
}

原因是你没有更改aCountbCountcCount,所以你最终会重复触发相同的情况。

除此之外,您似乎并没有真正递归地考虑问题 - 如另一个答案中所述,所有排列都出现在一个调用中,因此,如果您让它以这种方式工作,您的递归深度将2,这实际上可能涉及用打印语句替换每个递归调用,并具有非递归函数。

对于递归解决方案,请尝试考虑一种解决方案,在当前调用中处理单个字符,然后递归到下一个。

更详细的解释,如果你想不通:

  • 从第一个字符开始。
  • 尝试将当前字符与每个剩余字符(包括其自身,即什么都不做)交换。
  • 递归到下一个字符。
  • 在最后一个字符处,打印出所有字符。

  • 提示 - 将数组和当前索引传递给您的函数。

    【讨论】:

      【解决方案3】:

      我给你写伪代码:

      permutationABC()
      {
          int n=3;
          array SOL[n]/* 1 if you get the element  otherwise 0 if you don't get the element , the meaning of SOL is that SOL[0] is 1 if we had got 'a' , otherwise 0. It's the same for the others */
          initSolWithAllZero(SOL)
          permRecursive(abc,SOL,0,n);
      }
      
      permRecursive(SOL,i,n)
      {
          if i == n then print(SOL) 
          else
          {
              for k=0 to n
              {
                   if SOL[k] == 0 then
                   {
                        SOL[k]=1 // take 
                        permRecursive(SOL,i+1,n)
                        SOL[K]=0 // don't take ... go back....
                   }
              }
          }
      }
      

      时间是 O(n*n!) O(n!) 是排列的次数,O(n) 是打印时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-13
        • 2014-08-19
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 2011-07-23
        • 1970-01-01
        • 2020-04-13
        相关资源
        最近更新 更多