Algorithm thinking (recursively) Training: full array output string of characters

topic

Design an algorithm, the output of the whole arrangement of a character string. For example, String = "ABC" output is
ABC
ACB
BAC
BCA
the CBA
CAB

Thinking

Our first instinct is possible, this is a matter of choice, the first character of 3-to-1, 2-to-1 second character, the third character did not have a choice, three cycles of violence can be solved quickly. Nested loops can be used to generate a new string.

But the length of this string is uncertain, we do not have a syntax that can be specified cycle number of layers.

If the number of layers to be based operation, only recursion.

A recursive situation must abstract x, such that the lower part of the processing situation simplifies to y, the situation recursive solution y, and so on, until the problem is simple enough to be solved Clearly, then return to the layers.

When abstract recursion, we can imagine that I have a subsidiary, a subsidiary of another subsidiary, all these people can solve the same problem. The most senior leaders need to simplify the situation a little bit, then appointed after a similar situation to deal with subordinates can simplify this, then is waiting for the results.

In this question, we can consider this:

    目标:输出全排列(字符数组)
        我来搞定第一个字符
        剩下的事,下级来处理剩下的部分
        处理到最后一个字符时,就可以输出这个重新排列过的数组了

But soon you will find that the first character to get there are many choices, the above reasoning needs to be rewritten as:

    目标:输出全排列(字符数组)
        我来搞定第一个字符,这件事我会重复N次,每次选字符串中的一个
            一旦选定(把某个字符挪到首位)
            剩下的事,下级来处理剩下的部分
            因为下次我要再选一个,所以先恢复到挪位之前

So when the output of it?
This function is called once each, are lined up in front of superior character, I have to deal with subsequent characters, if I am dealing with is the last character, because superiors have lined up in front of me all the characters to the overall output.

Pseudo code

// data:上级给任务时字符数组,index:上级已经排好了0~index-1的字符,要我处理index~length-1这段
f(char[] data,int index)
    // 现在我试着从index开始找一个字符来作为首位,我要尝试length-indexfor(int i=index;i<length;i++)
        swap(data,i,index);// 把i位置的字符交换到index这里来,我的工作就完成了
        // 下面请直接下级来接招
        f(data,index+1);
        // 下级排好了,我即将选定下一个字符作为首位,必须先恢复一下
        swap(data,i,index);

    // 如果上级们已经处理好全部字符,我就输出
    if(index==length)
        println(data);

Java code

package org.lanqiao.algo.recursion;

/**
 * 输出字符串所有字符的全排列
 * */
public class StrPermutation {

  static int n;

  public static void main(String[] args) {
    String s = "ABCDE";
    permutation(s.toCharArray(), 0);
    System.out.println("---" + n + "---"); // n=长度的阶乘,可以用这个数字验证算法的正确性
  }


  //index代表0~index-1都已确认排列,[index,n-1]待排列
  private static void permutation(char[] arr, int index) {
    //至于什么时候输出,要考虑清楚
    //考虑:只有所有位置上的字符都确认即index到达末尾,才算是排好一种情况
    if (index == arr.length) {
      n++;
      System.out.println(String.valueOf(arr));
    }
    //现在index之前的字符都已就位,把之后的每个字符都交换到index这个位置
    for (int k = index; k < arr.length; k++) {
      //尝试交换
      swap(arr, index, k);
      //交换之后index这个位置就定好了,接下来的事就是递归去解决index+1位置开始的全排列就好了
      permutation(arr, index + 1);
      // 前面我们尝试交换,把全排列求出来了,交换时只尝试了一个字符,因此for循环继续之前要换回来,继续尝试交换下一个字符
      swap(arr, index, k);
    }
  }

  private static void swap(char[] arr, int index, int k) {
    if(k==index)
      return; // 不必交换了吧
    char tmp = arr[k];
    arr[k] = arr[index];
    arr[index] = tmp;
  }
}

summary

The final code is actually relatively brief, it is recursive features: the code is simple, the idea detour. Test of abstract thinking and imagination.
Recursive, you must find the similarity problem into sub-problems, in other words, you have to find some decomposition structure can be simplified to the disintegration direct link problem until conclusion.

Published 127 original articles · won 97 Like · views 310 000 +

Guess you like

Origin blog.csdn.net/zhengwei223/article/details/78627003