zoukankan      html  css  js  c++  java
  • 全排列合集

    不得不佩服这位大哥,算法钻研的这么细,说的还很清楚:http://blog.csdn.net/morewindows/article/details/7370155    算法并非照着贴来的,是我看了他的说明自己写的。

    去掉重复的非递归全排列:

    如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"、"52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0、2都不行,5可以,将5和2交换得到"956220",然后再将替换点后的字符串"6220"颠倒即得到"950226"。

    #include <string>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    class NRP
    {
    private:
        string __str;
        int __length, __num;
    public:
        NRP() {
            cout<<"please input a string: 
    ";
            while (cin >>__str) {
                __num = 0;
                __length = __str.length();
                sort(__str.begin(), __str.end());
                cout<<"start to output
    ";
                do
                {
                    cout<<__str<<endl;
                    __num++;
                } while (NextPermutation() == true);
                cout<<"the total number of permutation is :"<<__num<<endl;
                cout<<"please input a string: 
    ";
            }
        }
    
        ~NRP(){}
    
        bool NextPermutation() {
            int i;
            for (i = __length-2; i>=0 ; i--)
            {
                if (__str[i] < __str[i+1])
                {
                    char c = '';
                    int k;
                    for (int j = i+1; j< __length; j++)
                    {
                        if (__str[j] > __str[i])
                        {
                            if (c == '')
                            {
                                c = __str[j];
                                k = j;
                            }
                            else if (c >= __str[j]) //当存在重复字符时,也必须交换
                            {
                                c = __str[j];
                                k = j;
                            }
                        }
                    }
                    swap(__str[i], __str[k]);
                    reverse(__str.begin()+i+1, __str.end());
                    return true;
                }
            }
            return false;
        } 
    
    };
    
    void main()
    {
        NRP nrp;
    }
    

    去掉重复的递归全排列:

    这样我们也得到了在全排列中去掉重复的规则——去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。用编程的话描述就是第i个数与第j个数交换时,要求[i,j)中没有与第j个数相等的数。

    #include <iostream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    class Permutation
    {
    private:
        int n,sum;
        string str;
    public:
        Permutation()
        {
            cout<<"Please input a string: "<<endl;
            while (cin>>str)
            {
                n = str.length();
                sum = 0;
                getPerm(0);
                printSum();
                cout<<"Please input a string: "<<endl;
            }
        }
    
        ~Permutation(){}
    
        bool IsSwap(int nBegin, int nEnd)
        {
            for (int i = nBegin; i < nEnd; i++)
            {
                if (str[i] == str[nEnd])
                {
                    return false;
                }
            }
            return true;
        }
        void getPerm(int k)
        {
            if (k == n)
            {
                sum++;
                cout<<str<<endl;
            }
            else
            {
                for (int i = k; i < n;i++)// 如果只有4个元素  第一次为 swap(0,0)  swap(0,1) swap(0,2) swap(0,3)
                {
                    if (IsSwap(k, i) == true)
                    {
                        swap(str[i],str[k]);
                        getPerm(k+1);
                        swap(str[i],str[k]);
                    }
                }
            }
        }
        void printSum()
        {
            cout<<sum<<endl;
        }
    };
    
    void main()
    {
        Permutation perm;
    }
    

    纯STL的去掉重复的全排列:

    #include <iostream>
    #include <algorithm>
    #include <string>
    
    using namespace std;
    
    void main()
    {
        string str;
        cin >> str;
        sort(str.begin(), str.end());
        cout << str << endl;
        while (next_permutation(str.begin(), str.end()))
        {
            cout << str << endl;
        }
    }
    

      

  • 相关阅读:
    Codeforces 1045C Hyperspace Highways (看题解) 圆方树
    Codeforces 316E3 线段树 + 斐波那切数列 (看题解)
    Codeforces 803G Periodic RMQ Problem 线段树
    Codeforces 420D Cup Trick 平衡树
    Codeforces 295E Yaroslav and Points 线段树
    Codeforces 196E Opening Portals MST (看题解)
    Codeforces 653F Paper task SA
    Codeforces 542A Place Your Ad Here
    python基础 异常与返回
    mongodb 删除
  • 原文地址:https://www.cnblogs.com/kind064100611/p/4420437.html
Copyright © 2011-2022 走看看