您的位置:首页 > 其它

字符串全排列和组合算法

2015-10-16 01:39 453 查看

打印字符串的全排列

算法的思路:

把一个字符串分成两部分,第一个字符+后面部分所有的字符。这样就能够递归的求解整个过程了:

1.每个字符都做一次首字符
2.当某个字符作为首字符的时候,求后面所有字符的全排列

而这里的求后面所有字符的全排列可以看成递归的子问题


全排列的递归树:





但是这里还有一个问题,那就是字符串中有重复的字符时,这样的算法会增加最后的结果数目。比如说字符串aab,a+ab的全排列,然后交换还是a+ab的全排列。所以会增加结果的数目。解决方案就是:当遇到重复的字符的时候就跳过去,不在进行递归。

所以代码实现:

#include <iostream>
#include <algorithm>
using namespace std;

void getPermutation(char *pStr, char *pBegin);
void Permutation(char *pStr);

void Permutation(char *pStr)
{
if (pStr == NULL)
{
return;
}
getPermutation(pStr, pStr);
}

void getPermutation(char *pStr, char *pBegin)
{
if (*pBegin == '\0')
{
printf("%s\n", pStr);
}
else
{
for (char *pCh = pBegin; *pCh != '\0'; ++pCh)
{
//如果是相同的字符,那么就不用在递归,防止产生多余的字符串结果
if (*pCh == *pBegin && pCh != pBegin)
continue;

swap(*pCh, *pBegin);
getPermutation(pStr, pBegin + 1);
swap(*pCh, *pBegin);
}
}
}//getPermutation

int main()
{
char str[] = "aab";
//这里实参如果是char *str = "abc";是不可行的,因为常量字符串是不能交换的
Permutation(str);

return 0;
}


这是C语言版的实现,再看C++版本的实现:

vector<string> Permutation(string str)
{
vector<string> res;
if(str.size() == 0)
return res;

getPermutation(res, str, 0);

sort(res.begin(), res.end());
return res;
}

void getPermutation(vector<string>& res, string& str, int begin)
{
if(begin == str.size())
{
res.push_back(str);
}
else
{
for(unsigned int i = begin; i < str.size(); i++)
{
if(str[i] == str[begin] && i != begin)
continue;
swap(str[i], str[begin]);
getPermutation(res, str, begin + 1);
swap(str[i], str[begin]);
}//for
}
}//getPermutation


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: