zoukankan      html  css  js  c++  java
  • 用程序实现全排列(一)

    问题描述:

    给定一个整数n,按字典序打印出1-n的所有全排列

    问题解答:

    1.用C++里的next_permutation函数

    函数定义如下:

    template<class BidirectionalIterator>
    bool next_permutation(
          BidirectionalIterator _First, 
          BidirectionalIterator _Last
    );
    template<class BidirectionalIterator, class BinaryPredicate>
    bool next_permutation(
          BidirectionalIterator _First, 
          BidirectionalIterator _Last,
          BinaryPredicate _Comp
     );

    函数实现的原理:

    从序列的最后一个元素开始向前扫描,直到找到两个位置上相邻的元素*i,*j(i,j为下标,j = i+1)且*i<*j,再从尾端找一个元素*k,*i<*k,将*i与*k交换,并将*j及之后的元素全部倒置

    证明:

    设给定序列为a1a2...aiai+1ai+2...an,且ai,ai+1为逆序扫描第一个找到的正序,则有ai < ai+1 > ai+2 > ai+3 > ... > an,

    ①假设ai > ak (∀k∈{i+2,...n}),那么直接交换ai与ai+1,设所得序列为a1'a2'...ai'ai+1'ai+2' ... an',那么a1'=a1...ai-1'=ai,ai' = ai+1,ai+1'=ai,ai+2'=ai+2,...,an'=an

    再将ai+1'及之后的元素逆置一下,就可以得到ai+1'及之后字符的集合组成的串的最小字典序排列

    为什么这种是最小的呢?

    首先,如果改变ai之前的字符任意使得字典序变得更大,那么显然要比上述方法得到的字符串a1'...an'字典序要大;

    又ai+1及之后的串已经是完全逆序,所以只改变这部分得到的字符串字典序不会更大;

    ②假设存在k∈{i+2..n},使得ai<ak,证明类似

    ps:注意边界条件:当字符串已经为完全逆序(达到字典序最大)时,没有next_permutation

    函数代码:

    template<class BidirectionalIterator>
    bool next_permutation(
          BidirectionalIterator first, 
          BidirectionalIterator last
    )
    {
        if(first == last)
            return false; //空序列
    
        BidirectionalIterator i = first;
        ++i;
        if(i == last)
            return false;  //一个元素,没有下一个序列了
        
        i = last;
        --i;
    
        for(;;) {
            BidirectionalIterator ii = i;
            --i;
            if(*i < *ii) {
                BidirectionalIterator j = lase;
                while(!(*i < *--j));
    
                iter_swap(i, j);
                reverse(ii, last);
                return true;
            }
            
            if(i == first) {
                reverse(first, last);  //全逆向,即为最小字典序列,如cba变为abc
                return false;
            }
        }
    
    }
    

    使用:

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<string.h>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    int main()
    {
        int Array[5] = {1,2,3,4,5};
        for(int i = 0; i < 5; ++i)
        {
            printf("%d	",Array[i]);
        }
        printf("
    ");
        while(next_permutation(Array,Array + 5))
        {
            for(int i = 0; i < 5; ++i)
            {
                printf("%d	",Array[i]);
            }
            printf("
    ");
        }
        return 0;
    }    
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    Oracle数据库基础
    软件项目开发模式——三层模式
    JavaWeb——Ajax与MVC学习总结
    JavaWeb——EL及JSTL学习总结
    JavaWeb——过滤器及监听器
    JavaWeb——Servlet开发
  • 原文地址:https://www.cnblogs.com/warmfrog/p/3645733.html
Copyright © 2011-2022 走看看