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

来源:互联网 发布:面试技巧 知乎 编辑:程序博客网 时间:2024/05/17 20:29

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

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

1 0
原创粉丝点击