无重复全排列_非递归实现
Posted yuyaweibest
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无重复全排列_非递归实现相关的知识,希望对你有一定的参考价值。
无重复全排列_非递归实现
问题描述:用C++非递归方法输出无重复字符串的全排列。
解决思路与方案:首先将无重复字符串进行从小到大进行排序,从字符串的最后向前找到第一个递减字符,这个字符对应位置即为替换点1,再从字符串的最后往前找一个比替换点1对应的字符大,但在替换点1之后字符串中为最小,这时找到的字符对应位置为替换点2(即比替换点1对应字符大的最小字符),这个位置必然是存在。然后交换替换点1和2对应的字符,此时替换点1对应的字符变成了替换点2对应的字符,最后将替换点1位置之后的字符串颠倒,输出此时的排列,即为一种不重复的排列。依次循环下去,直到字符串从大到小这种最“大”的排列,再将此时最“大”的排列颠倒至最小排列,并返回false。
举个简单例子来说明:以”916520”这个字符串为例,我们从后向前找第一个递减字符(从后向前的递减),”20”、”52”、”65”都是递增的,”16 “即满足要求,称数字1对应位置为替换点1,再从后面找一个比替换数大的最小数(这个数必然存在),0不行,2、5、6都大于1,但只有2为最小数,可以,将1和2交换得到”926510”,然后再将替换点1位置后的字符串”6510”颠倒即得到”920156”,返回true,输出这个字符串。循环下去,直到“012569”,颠倒,返回false,结束。
C++代码实现:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
using namespace std;
void Swap(char *a, char *b);
void Reverse(char *a, char *b);
bool Next(char a[]);
int Qsort(const void *pa, const void *pb);
int main()
cout<<"全排列的非递归实现 "<<endl;
char szTextStr[] = "badc";
cout<<szTextStr<<"的全排列如下:"<<endl;
qsort(szTextStr, strlen(szTextStr), sizeof(szTextStr[0]), Qsort); //加上排序
int i = 1;
do
cout<<"第"<<i++<<"个排列: "<<szTextStr<<endl;
while (Next(szTextStr)); //do...while语句,未验证Next的返回值之前已经执行do一次
cin.get();
return 0;
void Swap(char *a, char *b)
char t = *a;
*a = *b;
*b = t;
void Reverse(char *a, char *b) //反转区间
while (a < b)
Swap(a++, b--);
bool Next(char a[]) //下一个排列
char *pEnd = a + strlen(a);
if (a == pEnd)
return false;
char *p, *q, *pFind;
pEnd--;
p = pEnd;
while (p != a)
q = p;
--p;
if (*p < *q) //找降序的相邻2数,前一个数即替换数
//从后向前找比替换点大的第一个数
pFind = pEnd;
while (*pFind <= *p)
--pFind;
Swap(pFind, p); //替换
Reverse(q, pEnd); //替换点后的数全部反转
return true;
Reverse(p, pEnd); //如果没有下一个排列,全部反转后返回true
return false;
int Qsort(const void *pa, const void *pb)
return *(char*)pa - *(char*)pb;
输出:
其他测试类似(只需改变szTextStr字符串),均能输出正确结果,实验成功!
代码分析:
(1)排序算法,我们调用编译器函数自带快速排序函数,函数包含在头文件stdlib.h
用法: void qsort(void base,int nelem,int width,int (*fcmp)(const void ,const void *));
参数:1 待排序数组首地址
2 数组中待排序元素数量
3 各元素的占用空间大小
4 指向函数的指针,用于确定排序的顺序
参数4,我们用了int Qsort(const void *pa, const void *pb)函数,该函数决定了由小到大进行排序。
(2)从后向前找替换点的位置2时,根据要求,我们需要比替换点1对应字符大的最小字符。具体实现是,我们从后向前找,比替换点1对应字符大的第一个字符即为满足要求的字符,这点比较抽象,大家可以自行找字符串来手动测试验证。
以上是关于无重复全排列_非递归实现的主要内容,如果未能解决你的问题,请参考以下文章