无重复全排列_非递归实现

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对应字符大的第一个字符即为满足要求的字符,这点比较抽象,大家可以自行找字符串来手动测试验证。

以上是关于无重复全排列_非递归实现的主要内容,如果未能解决你的问题,请参考以下文章

无重复全排列

python 全排列 递归中的两种实现

python 全排列 递归中的两种实现

全排列 递归实现

有重复全排列

力扣784. 字母大小写全排列 回溯法 C++递归和非递归俩种实现非方式