字符串全排列问题

2017-01-13  本文已影响0人  pw007992

今天学习了字符串全排列问题的递归与非递归实现,其中,递归实现是把递归放在循环中,到现在我也没看懂到底是个什么样的过程。不过非递归的算法倒是看懂了,终于理解了一句话:如果算法思路有了,实现根本就不是问题。可我们常常做的一件事就是思路并不怎么清晰,就开始写代码,然后通过一点点调试直到正确。其实这样是不对的,以后要端正编码的态度,思路完全清晰了才能开始写代码。好了,扯了一堆废话,下面开始正题吧。

首先,所谓字符串全排列问题,就是给定一个字符串,写出以该字符串生成的所有排列的字符串。例如abc,通过全排列可以生成6个字符串:abc,acb,bac,bca,cba,cab。
先说一下它的非递归算法的思路:
1.先将字符串中的字符从下到大排序。
2.从后往前找到第一个相邻的递增字符对,设该字符对中的第一个叫替换数A,其位置(下标)叫做替换点a,然后我们从后往前找到第一个大于A的字符B,交换A和B,让后将位置a之后的字符串颠倒。
3.这样重复操作(通过传引用实现),知道字符串中再也找不到相邻的递增字符对,表示全排列已经结束了.
题目:字符串的排列
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

代码:

class Solution {
public:
    bool hasNext(string& str){
        if(str.size() < 2)
            return false;
        int pos = str.size() - 2;
        while(pos >= 0){//找替换数
            if(str[pos] >= str[pos + 1])
                pos --;
            else
                break;
        }
        if(pos == -1)//表示所有相邻字符对都是递减的了,全排列结束
            return false;
        
        char val = str[pos];
        int i = str.size() - 1;
        for(; i > pos; i --){//找替换点后面第一个大于替换数的数
          if(val < str[i])
              break;
        }
        swap(str[pos], str[i]);
        int start = pos + 1;
        int last = str.size() - 1;
        while(start < last)//将替换点后的字符串颠倒
            swap(str[start ++], str[last --]);
        
        return true;
    }
    
    vector<string> Permutation(string str) {
        vector<string> ret;
        if(str.size() == 0)
            return ret;
        
        sort(str.begin(), str.end());
        ret.push_back(str);
        while(hasNext(str)){
            ret.push_back(str);//传引用
        }
        return ret;
    }
};
上一篇下一篇

猜你喜欢

热点阅读