因为前段时间的一道面试题,我开始关注递归了。
全排列如果用迭代相当麻烦。
一定要记得递归的要素。
比如a b c,如何进行迭代呢。比如Permute(str,3)
先想最简单的情况 怎么搞嘛,没思路。
其实排列是基于这样一个事实,就是每个字母都机会做首位。
a**
b**
c**
就是可以先确定首字母,这就剩下2个字母了,剩下的2个字母,是一样的办法,先确定首字母,好!问题可以被分解。
但如何分别把每个字母搞到第一个呢?
这个easy,遍历字符串,把第一个字母和那个字母位置交换位置就行了。
然后迭代;
接着需要把交换的字母复位,因为迭代的一个重要点就是不能把上次的迭代影响下一次。这个也简单,再交换一次位置就复位了。
我们可以看看这部分的代码是如何的:
DoPermute(pStr,k):
int len = strlen(pStr);
{
for (int i=k; i < len; ++i)
{
Exchange(pStr,i,k);
DoPermute(pStr,k+1);
Exchange(pStr,i,k);
}
}
其中的DoPermuter就是迭代函数,为毛要如此写?
1.Exchange(pStr,i,k);其实已经得到第一个字母了;
2.DoPermute(pStr,k+1);接着迭代找到下一个;
这样子k是一直增加的,如何使迭代停止呢。
当然最大是数组大小啦!
所以应该加上停止条件:
void DoPermute(char* pStr, int k)
{
int len = strlen(pStr);
if (k == len)
{
printf("%s \n",pStr);
}
else
{
for (int i=k; i < len; ++i)
{
Exchange(pStr,i,k);
DoPermute(pStr,k+1);
Exchange(pStr,i,k);
}
}
}
最后Exchange(pStr,i,k);是复位。
好,这样就完成了全排列。
还是贴上全部代码吧,免得以后找的麻烦:
#include "stdio.h"
#include "string.h"
void Exchange(char* pStr,int i,int j)
{
char temp = pStr[i];
pStr[i] = pStr[j];
pStr[j] = temp;
}
void DoPermute(char* pStr, int k)
{
int len = strlen(pStr);
if (k == len)
{
printf("%s \n", pStr);
}
else
{
for (int i=k; i < len; ++i)
{
Exchange(pStr,i,k);
DoPermute(pStr,k+1);
Exchange(pStr,i,k);
}
}
}
void RecursivePermute(char* pStr)
{
DoPermute(pStr,0);
}
int main()
{
char temp[] = "abcde";
RecursivePermute(temp);
}