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

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

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值