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

      全排列属于组合数学的知识,有序数法,字典序法,临位互换法,本文着重从字典序法(stl中的Next_permutation也是使用此法)对字符串s进行全排列。具体算法如下:

      I)从后往前找到第一个j,使得s[j]<s[j+1],若未找到,即j=-1时结束

         II)从后往前找到第一个k,使得s[k] > s[j],然后交换s[k],s[j]

         III)将s[j+1:n]倒置

         对于这种算法是如何得到全排列的证明如下:

         1.子串s[j+1:n]是单调递减的,即对于前半部分为s[0:j]的当前字符串而言,后半部分是全排列的最大值

         2.s[k]是从后往前找到的第一个大于s[j]的字符,所以交换后,得到的字符串是下一轮排列的最大值

         故只要将s[j+1:n](交换后)倒置即得到next_permutation

    #include <stdio.h>
    #include <string.h>
    #define swap(a,b){char tmp=a;a=b;b=tmp;} //a=a+b;b=a-b;a=a-b;
    #define N 50
    
    void Permutation(char *s){
        int i,j,k;
        while(1){
            puts(s);
            for(j = strlen(s) - 2 ; j >= 0 ; j --)
                if(s[j] < s[j+1]){ //第一个比右边小 
                    break;
                }
            if(j == -1) break; //已得到最大全排列 
            for(i = strlen(s) - 1 ; i >= 0 ; i -- )
                if(s[i] > s[j]){
                    swap(s[i],s[j]);
                    break; //need break
                }
            for(i = j + 1 ; i <= (strlen(s)-1+j)/2 ; i ++ ) //从j开始的子串倒置,need"=" 
                 swap(s[i],s[strlen(s)+j-i]);
        }
    }
    
    int main(){
        char s[N] = "1234";
        Permutation(s);
        return 0;
    }

    显然,我们注意到字典序法适用于:无重复但需要初始状态按ascii码升序字符串全排列

    对于存在重复的字符串以及有序数法和临位互换法的实现将在以后的文章中讲解。。。

    参考资料:

      http://blog.csdn.net/cpfeed/article/details/7376132

  • 相关阅读:
    Spring中使用ActiveMQ发送邮件
    Active MQ技术文章(JMS)
    java并发编程Executor框架
    java并发编程构建块
    Java:定时启动线程
    java的concurrent用法详解
    jms activeMQ与spring集成进阶篇(转载)
    python练习程序(读写文件)
    python练习程序(下载网页)
    简单工厂模式(C++)
  • 原文地址:https://www.cnblogs.com/emptyCoder/p/6414521.html
Copyright © 2011-2022 走看看