代码改变世界

字符串的全排列问题

2011-08-20 00:35  Daniel Zheng  阅读(390)  评论(0编辑  收藏  举报

对于一个字符串abc, 求它的全排列可以这样分析:

  • 第一个字符为a时,bc的全排列
  • 第一个字符为b时,ac的全排列
  • 第一个字符为c时,ab的全排列
对上述各种情况的子串采用相同的方法,直到子串只有一个字符为止,全排列就是它自身。
各处代码:
void swap(char * a, char * b)
{
char temp = *a;
*a = *b;
*b = temp;
}
void permutation(char *s, int start, int end)  //end = strlen(s)
{
int i;
if (start == end) {
printf(
"%s\n", s);
}
else {
for (i = start; i < end; i++) {
swap(
&s[start], &s[i]);
permutation(s, start
+ 1, end);
 
swap(&s[start], &s[i]); //start及其后面的每一个元素都要与start位置上的元素交换,所以要对上一次交换的结果复原
        }  
}
}

 以上代码执行过程:

  为什么要复原?对于abc,b,c又要与a交换,所以 abc->bac->(abc)->cba, 如果不复原则为abc->bac->cab, 不符合递归的规则。

  对上面的swap函数,我本来使用的如下形式:

void swap(char * a, char * b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}

  上面这个函数当a与b指向同一个地址时,a与b指向的值同时更新,永远相同,所以到的结果是*a = 0, *b = 0。

  解决办法:进入函数时判断a与b是否指向同一地址:

void swap(char * a, char * b)
{
if(a == b)
return;
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}