zoukankan      html  css  js  c++  java
  • 字符串的全排列

    字符串的全排列问题:

    给定字符串S[0...N-1],设计算法,枚举字符串的全排列。

    1、无重复字符串全排列非递归算法

    程序实现:

     1 //无重复字符串的全排列递归算法
     2 void Permutaion(int* a,int size,int index){
     3     if(index == size-1){
     4         Print(a,size);
     5         return;
     6     }
     7     for(int i=index;i<size;i++){
     8         swap(a[i],a[index]);
     9         Permutaion(a,size,index+1);
    10         swap(a[i],a[index]);
    11     }
    12 }

    运行结果:

    说明:在每次递归前需要保证字符串的顺序不变,因此有每次的替换过程。

    2、有重复字符串队规算法

    程序实现:

     1 //判断从a[to]是否与(index,to)重复
     2 bool IsDuplicate(int* a,int index,int to){
     3     while(index<to){
     4         if(a[index]==a[to]){
     5             return true;
     6         }
     7         index++;
     8     }
     9     return false;
    10 }
    11 //有重复字符串的全排列递归算法,Time Cost O((n+1)!)
    12 void Permutaion1(int* a,int size,int index){
    13     if(index == size-1){
    14         Print(a,size);
    15         return;
    16     }
    17     for(int i=index;i<size;i++){
    18         if(!IsDuplicate(a,index,i)){
    19             swap(a[i],a[index]);
    20             Permutaion1(a,size,index+1);
    21             swap(a[i],a[index]);
    22         }
    23     }
    24 }

    运行结果:

    说明:本算法时间复杂度能达到O((n+1)!),不可取。

    改进:利用空间换时间,采用下列的程序实现:

     1 //有重复字符串的全排列递归算法,空间换时间
     2 void Permutaion2(int* a,int size,int index){
     3     if(index == size-1){
     4         Print(a,size);
     5         return;
     6     }
     7     int dup[256] = {0};
     8     for(int i=index;i<size;i++){
     9         if(dup[a[i]]==1)
    10             continue;
    11         dup[a[i]] = 1;
    12         swap(a[i],a[index]);
    13         Permutaion2(a,size,index+1);
    14         swap(a[i],a[index]);
    15     }
    16 }

    运行结果:

    3、使用求下一个排列的思想,构造非递归算法。

    过程:从当前排列生成字典序刚好比它大的下一个排列。

    程序实现:

     1 //字符串全排列非递归算法,求下一个排列的思想
     2 void Reverse(int* from,int* to){
     3     int t;
     4     while(from<to){
     5         t = *from;
     6         *from = *to;
     7         *to = t;
     8         from++;
     9         to --;
    10     }
    11 }
    12 bool GetNextPermutation(int* a,int size){
    13     //后找,从后向前找最后一个升序的位置
    14     int i = size-2;
    15     while((i>=0)&&(a[i]>=a[i+1]))
    16         i--;
    17     if(i<0) return false;
    18     //查找,从后面的元素中寻找比a[i]大的最小值a[j]
    19     int j=size-1;
    20     while(a[j]<=a[i])
    21         j--;
    22     //交换
    23     swap(a[i],a[j]);
    24     //翻转 a[i+1...N-1]
    25     Reverse(a+i+1,a+size-1);
    26     return true;
    27 }

    运行结果:

    说明:非递归算法天然解决重复字符问题。

    另附上全部实现程序,仅供参考:

      1 /***************************************
      2 FileName StringPermutation.cpp
      3 Author : godfrey
      4 CreatedTime : 2016/5/1
      5 ****************************************/
      6 #include <iostream>
      7 #include <cstring>
      8 #include <vector>
      9 #include <algorithm>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 
     13 using namespace std;
     14 
     15 void Print(const int* a,int size){
     16     for(int i=0;i<size;i++){
     17         cout<<a[i]<<' ';
     18     }
     19     cout<<endl;
     20 }
     21 //无重复字符串的全排列递归算法
     22 void Permutaion(int* a,int size,int index){
     23     if(index == size-1){
     24         Print(a,size);
     25         return;
     26     }
     27     for(int i=index;i<size;i++){
     28         swap(a[i],a[index]);
     29         Permutaion(a,size,index+1);
     30         swap(a[i],a[index]);
     31     }
     32 }
     33 //判断从a[to]是否与(index,to)重复
     34 bool IsDuplicate(int* a,int index,int to){
     35     while(index<to){
     36         if(a[index]==a[to]){
     37             return true;
     38         }
     39         index++;
     40     }
     41     return false;
     42 }
     43 //有重复字符串的全排列递归算法,Time Cost O((n+1)!)
     44 void Permutaion1(int* a,int size,int index){
     45     if(index == size-1){
     46         Print(a,size);
     47         return;
     48     }
     49     for(int i=index;i<size;i++){
     50         if(!IsDuplicate(a,index,i)){
     51             swap(a[i],a[index]);
     52             Permutaion1(a,size,index+1);
     53             swap(a[i],a[index]);
     54         }
     55     }
     56 }
     57 //有重复字符串的全排列递归算法,空间换时间
     58 void Permutaion2(int* a,int size,int index){
     59     if(index == size-1){
     60         Print(a,size);
     61         return;
     62     }
     63     int dup[256] = {0};
     64     for(int i=index;i<size;i++){
     65         if(dup[a[i]]==1)
     66             continue;
     67         dup[a[i]] = 1;
     68         swap(a[i],a[index]);
     69         Permutaion2(a,size,index+1);
     70         swap(a[i],a[index]);
     71     }
     72 }
     73 //字符串全排列非递归算法,求下一个排列的思想
     74 void Reverse(int* from,int* to){
     75     int t;
     76     while(from<to){
     77         t = *from;
     78         *from = *to;
     79         *to = t;
     80         from++;
     81         to --;
     82     }
     83 }
     84 bool GetNextPermutation(int* a,int size){
     85     //后找,从后向前找最后一个升序的位置
     86     int i = size-2;
     87     while((i>=0)&&(a[i]>=a[i+1]))
     88         i--;
     89     if(i<0) return false;
     90     //查找,从后面的元素中寻找比a[i]大的最小值a[j]
     91     int j=size-1;
     92     while(a[j]<=a[i])
     93         j--;
     94     //交换
     95     swap(a[i],a[j]);
     96     //翻转 a[i+1...N-1]
     97     Reverse(a+i+1,a+size-1);
     98     return true;
     99 }
    100 int main()
    101 {
    102     int a[] = {1,2,3,4};
    103     cout<<"-----无重复字符串全排列递归算法-------"<<endl;
    104     Permutaion(a,sizeof(a)/sizeof(int),0);
    105     int a1[] = {1,2,2,3};
    106     cout<<"-----有重复字符串全排列递归算法-------"<<endl;
    107     Permutaion1(a1,sizeof(a1)/sizeof(int),0);
    108     cout<<"-----有重复字符串全排列递归算法(空间换时间)-------"<<endl;
    109     Permutaion2(a1,sizeof(a1)/sizeof(int),0);
    110     cout<<"-----字符串全排列非递归算法------------"<<endl;
    111     int size = sizeof(a)/sizeof(int);
    112     Print(a,size);
    113     while(GetNextPermutation(a,size))
    114         Print(a,size);
    115     return 0;
    116 }

    转载请注明出处:

    C++博客园:godfrey_88

    http://www.cnblogs.com/gaobaoru-articles/

    转载请注明出处: C++博客园:godfrey_88 http://www.cnblogs.com/gaobaoru-articles/
  • 相关阅读:
    解决显示器闪屏的问题
    装完系统后由于分辨率问题不能进入系统怎么办?怎么能不进入系统设置分表率?
    如何设置win7任务栏的计算机快速启动
    【转载】Oracle层次查询和分析函数
    【原创】birt 报表工具 不能运行 不能预览问题
    【转】最牛B的编码套路
    Windows下python环境配置
    python:numpy 下载
    TEX(LaTEX)输出PDF设置US LETTER或者LETTERPAPER办法
    Adobe Illustrator Cs6【AI cs6】中文破解版安装图文教程、破解注册方法
  • 原文地址:https://www.cnblogs.com/gaobaoru-articles/p/5450763.html
Copyright © 2011-2022 走看看