簡體   English   中英

理解字符串置換遞歸案例之間的區別

[英]understanding the difference Between string permutation Recursive cases

   class RecursionExample
       {
           private static void doPermute(String str, int l, int r)
            {
                if (l == r)
                    Console.WriteLine(str);
                else
                {
                    for (int i = l; i <= r; i++)
                    {
                        str = swap(str, l, i);
                        doPermute(str, l + 1, r);
                        str = swap(str, l, i);
                    }
                }
            }

            public static String swap(String a,int i, int j)
            {
                char temp;
                char[] charArray = a.ToCharArray();
                temp = charArray[i];
                charArray[i] = charArray[j];
                charArray[j] = temp;
                string s = new string(charArray);
                return s;
            }

            public static void Main()
            {
                String str = "ABC";
                int n = str.Length;
                doPermute(str, 0, n - 1);
            }
     }

相比

class RecursionExample
    {
        private static void doPermute(String str, int l, int r)
        {
            if (l == r)
                Console.WriteLine(str);
            else
            {
                for (int i = l; i <= r; i++)
                {
                    str = swap(str, l, i);
                    doPermute(str, l + 1, r);
                }
            }
        }

        public static String swap(String a,int i, int j)
        {
            char temp;
            char[] charArray = a.ToCharArray();
            temp = charArray[i];
            charArray[i] = charArray[j];
            charArray[j] = temp;
            string s = new string(charArray);
            return s;
        }

        public static void Main()
        {
            String str = "ABC";
            int n = str.Length;
            doPermute(str, 0, n - 1);
        }
 }

兩者都打印出完全相同的東西,不同之處在於第一個在置換遞歸調用之后調用交換方法。 根據我在網上閱讀的內容,底部交換是“回溯”到前一個案例,但它可以很好地回溯而無需進行額外的交換? 有人可以解釋我缺少或不理解的內容嗎? 對我來說,底部對我來說更有意義。

所以我只是浪費了 5 分鍾研究排列算法......呃。

回溯僅在您使用直接內存或引用時有用。 由於字符串C# 中不可變的,因此更改不會通過遞歸堆棧推回,因此回溯對於將狀態返回到其先前的預先撤回狀態沒有用(本質上無論如何都不會改變)

但是,如果您使用ref (或數組或類似的東西),您不僅會發現您的輸入發生了變異,更糟糕的是您會收到錯誤的結果。 時期。

例子

private static void doPermute(ref string str, int l, int r)
{
   if (l == r)
      Console.WriteLine(str);
   else
   {
      for (int i = l; i <= r; i++)
      {
         str = swap(str, l, i);
         doPermute(ref str, l + 1, r);
         str = swap(str, l, i);

      }
   }
}

帶回溯的輸出

ABC
ACB
BAC
BCA
CBA
CAB

沒有回溯的輸出

ABC
ACB
CAB
CBA
ABC
ACB

總之,如果您不使用直接內存或引用,它就沒有任何用處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM