题目类似剑指offer的第28题,这里在粘贴一下:题目:输入一个字符串,打印出该字符串中字符放入所有排列。例如输入字符串abc,则打印出字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
递归的实现算法:http://blog.csdn.net/moses1213/article/details/51055692
这里用非递归的算法实现:
假设有字符串p1 p2…pj-1pj pj+1…pk-1 pk pk+1…pn ,对字符串进行快速排序,得到所有排列中的最小值,然后寻找下一个排列,下一个排列比当前值大,而且是所有排列中比当前值大的最小排列。直到排列已是最大值,不再寻找下一个排列,此时从最小到最大全部实现,即为字符串的全排列。下面是下一个排列的算法步骤:
(1)从排列的尾部(最右边)开始, 找出第一个比右边相邻数字小的索引j ( j 从首部开始计算), 即j = max{i | pi < pi+1};
(2)在pj 右边的数字中, 找出所有比pj 大的数字中最小的数字的索引k, 即k= max{i | pi > pj};由于pj 右边的数字是从右至左递增的, 因此k 是所有大于pj 的数字中索引最大的;
(3) 交换pj 与pk;
(4) 将pj+1...pk-1, pj, pk+1...pn 翻转得到p的下一个排列p′
算法的证明见:http://www.doc88.com/p-6438124960748.html
#include <iostream>
#include <cstring>
using namespace std;
void Swap(char* a, char* b)
{
char temp = *a;
*a = *b;
*b = temp;
}
void Reverse(char* p1, char* p2)
{
while(p1 < p2)
Swap(p1++, p2--);
}
//非递归版本实现
bool NextPermutation(char* pStr)
{
char* pEnd = pStr + strlen(pStr) - 1;
char* pSwap = pEnd;
char* index;
//寻找替换数
for(index = pEnd - 1; index >= pStr; --index)
{
if(*index < *(index + 1))
{
pSwap = index;
break;
}
}
//pSwap没更新,即不存在这样的替换数,表明已是最大值
if(pSwap == pEnd)
<span style="white-space:pre"> </span>return false;
//寻找比*pSwap大的最小数
char* pMinLarger = pSwap + 1;
for(index = pMinLarger + 1; index <= pEnd; ++index)
{
if(*index > *pSwap && *index <= *pMinLarger)
pMinLarger = index;
}
Swap(pSwap, pMinLarger);
Reverse(pSwap + 1, pEnd);
return true;
}
int cmp(const void *a,const void *b)
{
return int(*(char *)a - *(char *)b);
}
int main(void)
{
char str[] = "13223";
qsort(str , strlen(str),sizeof(char),cmp);
do
cout << str << endl;
while(NextPermutation(str));
return 0;
}