c++字符串全排列递归法

来源:互联网 发布:腾讯tgp客户端mac 编辑:程序博客网 时间:2024/05/18 22:43

网上关于字符串全排列的代码一大堆,总体而言分为递归法和非递归法两种实现。虽然递归法原理简单,代码简洁,但是我观察众多博客来看,没有把代码讲透,只有透过代码才能看清算法的本质。

问题:输入一字符串(要求不存在重复字符),打印出该字符串中字符中字符的所有排列。
例如:输入”abc”,输出结果为abc, acb, bac, bca, cab和cba。

递归思路:看成两步:

1、首先求所有可能出现在第一个位置的字符,可以把第一个字符和后面的字符一次交换;2、固定第一个字符后,求后面字符的全排列,过程类似第一个字符的取法,即递归调用

也可以这么理解,f(abc) = a + f(bc), f(bc) = b + f(c),

讲了基本的思想,我们还是重点来看代码(这是网上摘抄,非作者本人所写),通过代码就能很好的理解了。

#include<iostream>  using namespace std;  #include<assert.h>  void Permutation(char* sourceStr, char* changeStr)  {      assert(sourceStr && changeStr);//断言,防止越界      if(*changeStr== '\0')          printf("%s\n",sourceStr);//如果没有可交换字母,已经到末尾,将源字符串输出     else      {      //比如源字符串当前是sourceStr="abc",交换字符串也为changeStr="abc",    //需要注意的是,函数void Permutation(str,str)传的是指向同一个字符串的指针        for(char* pCh = changeStr; *pCh != '\0'; pCh++)          {              swap(*changeStr,*pCh);//交换第一个和后面一个              Permutation(sourceStr, changeStr+1);//固定前面的,后面再排列              swap(*changeStr,*pCh);//再换回原来的          }      }    //一次完整的打印是这样的,首先sourceStr、changeStr都指向"abc",接着swap第一个,结果还是"abc",//这个时候就会输出'abc'。接着会退回的固定'a','b'和'c'进行交换,这个时候//sourceStr="acb",经过后面全排列后,又会换回来,这样"acb"也就打印出来 }  int main(void)  {      char str[] = "abc";      Permutation(str,str);      return 0;  }  

自己可以画图,将流程走一遍,或者设置断点调试,就能清楚的看到实现的机制了。

原创粉丝点击