zoukankan      html  css  js  c++  java
  • 排列组合-按字典次序生成n!排列

    //按字典次序生成集合的排列
    //一个有n个不重复元素{123...n}的集合S,有n!个不同排列。
    //他的最小排列是123...n,最大排列是n(n-1)...1
    //S的字典次序排列是指从其最小排列123...n开始到最大排列n(n-1)...1为止,
    //每一个当前排列比下一个排列小。
    //生成集合S的字典次序的排列算法如下:
    //1)将最小排列123...n作为当前排列
    //2)从右向左找到第一个变换位置
    //2.1)第一个变换位置的特点是它小于与其相邻的右边的元素,并且它右边的排列是它右边所有元素的最大排列。
    //2.2)找到变换位置后,再在其右边所有比变换位元素大的元素中找到一个最小的元素,将这个最小元素与变换位元素交换。
    //2.3)再将变换位右边的所有元素按升序排列,得到的这个新排列即是前面的当前排列的下一排列。
    //3)如此反复,直到最后一个排列。

    //生成P(n,r)的排列,可以先生成C(n,r)子集排列,然后对每个r子集进行P(r,r)排列。
    public class Permutation
    {
        public static void main(String[] args)
        {
            //指定集合的元素个数N
            int N=Integer.parseInt(args[0]);
            //使用一个长度为N的一维数组来表示这个排列
            int[] p=new int[N];
            //初值为123...n
            for(int i=0;i<p.length;i++)
                p[i]=i+1;
            show(p);
           //
            int i,j;
            int l,r;
            //当前排列不是最后一个排列时就继续生成下一个排列
            while(true)
            {
                //从右向左找第一个变换位i,特点是p[i]<p[i+1]
                for(i=N-2;i>=0 && p[i]>p[i+1];i--);
                //如果找不到变换位,说明当前排列已是最大排列,结束生成排列。
                if (i<0) break;
                //找到变换位后,在变换位的右边找比他大的最小元素这p[j](有p[j]=p[i]+1)
                for(j=N-1;j>i && p[i]>p[j];j--);
                //找到比变换元素p[i]大的最小元素p[j]后交换两元素
                exch (p,i,j);
                //变换位右边的元素按升序排列
                //在i,j元素交换前变换位右边的元素已是降序排列,i,j位置的元素交换后这个性质仍成立,所以右边的降序排列变更为升序排列时两端向中间交换即可得到
                l=i+1;
                r=N-1;
                while(l<r)
                   exch(p,l++,r--);
                //显示排列   
                show(p);
            }
        }
      
        private static void exch(int[] a,int i,int j)
        {
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
        //显示这个数组中的值
        private static void show(int[] a)
        {
            for(int i=0;i<a.length;i++)
                StdOut.printf("%d",a[i]);
            StdOut.println();
        }
    }

  • 相关阅读:
    11.【原创】Object.keys()的一般用法
    5. 【原创】table设置text-overflow: ellipsis;(超出范围显示...)不生效
    12.【转载】vscode默认常用快捷键
    13.【原创】JS读取apk安装包的信息,做应用上传
    11.【原创】chrom文件上传后,手动释放内存
    26.Mysql "truncate"与"delete"的区别
    25.【转载】Mysql timestamp类型字段的CURRENT_TIMESTAMP与ON UPDATE CURRENT_TIMESTAMP属性
    bof
    ctf Wiener tricky
    分解大素数
  • 原文地址:https://www.cnblogs.com/longjin2018/p/9868598.html
Copyright © 2011-2022 走看看