Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 626|回复: 0

[算法学习]字典序法生成全排列

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-24 00:05:22 | 显示全部楼层 |阅读模式
    字典序列算法
                                                                                        
         字典序列算法是一种非递归算法。而它正是STL中Next_permutation的实现算法。我们来看看他的思路吧:
    它的整体思想是让排列成为可递推的数列,也就是说从前一状态的排列,可以推出一种新的状态,直到最终状态。比如说,最初状态是12345,最终状态是54321。其实我觉得这跟我们手动做全排列是一样的。首先是12345,然后12354,然后12435,12453....逐渐地从后往前递增。 看看算法描述:
         首先,将待排序列变成有序(升序)序列。然后,从后向前寻找,找到相邻的两个元素,Ti<Tj,(j=i+1)。如果没有找到,则说明整个序列已经是降序排列了,也就是说到达最终状态54321了。此时,全排列结束。

         接着,如果没有结束,从后向前找到第一个元素Tk,使得Tk>Ti(很多时候k=j),找到它,交换Ti跟Tk,并且将Tj到Tn(Tn是最后一个元素)的子序列进行倒置操作。输出此序列。并回到第二步继续寻找ij.
      
      
      例如839647521是数字1~9的一个排列。从它生成下一个排列的步骤如下:
       自右至左找出排列中第一个比右边数字小的数字4    839647521
       在该数字后的数字中找出比4大的数中最小的一个5    839647521
       将5与4交换 839657421
       将7421倒转 839651247
       所以839647521的下一个排列是839651247。
       839651247的下一个排列是839651274。
    (注:何谓按字典序排列
    对两个字符串,先按字典顺序比较第一个字符,第一个字符相同的,比较第二字符,依此类推。。。
    例:字符集{1,2,3},较小的数字较先,这样按字典序生成的全排列是:123,132,213,231,312,321。)
    1. import java.util.Scanner;
    2. public class S1 {
    3.         /**
    4.          * @param args
    5.          */
    6.         public static void main(String[] args) {
    7.                 // TODO 自动生成方法存根
    8.                 S1 a = new S1();
    9.                 Scanner input = new Scanner(System.in);
    10.                 System.out.print("请输入要排列的元素有多少种:");
    11.                 int count = input.nextInt();
    12.                 int[] p = new int[count];
    13.                 for (int i = 1; i <= p.length; i++) {
    14.                         p[i-1] = i;
    15.                 }
    16.                 boolean con;
    17.                 do {
    18.                         a.pr(p);//输出排列p
    19.                         con = a.next(p);//求出按字典序排列的下一个排列p
    20.                 } while (con);
    21.         }
    22.         public int indexof(int[] n) {
    23.                 int index = -1;
    24.                 for (int i = n.length - 1; i >= 1; i--) {
    25.                         if (n[i-1] < n[i]) {
    26.                                 index = i - 1;
    27.                                 break;
    28.                         }
    29.                 }
    30.                 return index;
    31.         }
    32.         public int indexmin(int ini, int[] n) {
    33.                 int index = n.length - 1;
    34.                 int min = n[ini + 1];
    35.                 for (int i = ini + 1; i < n.length; i++) {
    36.                         if (n[i] <= min && n[i] > n[ini]) {
    37.                                 min = n[ i ];
    38.                                 index = i;
    39.                         }
    40.                 }
    41.                 return index;
    42.         }
    43.         public void swap(int index1, int index2, int[] n) {
    44.                 int temp;
    45.                 temp = n[index1];
    46.                 n[index1] = n[index2];
    47.                 n[index2] = temp;
    48.         }
    49.         public void oppositeDirection(int index1, int[] n) {
    50.            for (int i = index1 + 1, j = n.length - 1, k = 0, temp; k <= (n.length - i) / 2; i++, j--, k++) {
    51.                         temp = n[i];
    52.                         n[i] = n[j];
    53.                         n[j] = temp;
    54.                 }
    55.         }
    56.         public boolean next(int[] n) {
    57.                 int index1 = indexof(n);
    58.                 if (index1 == -1) {
    59.                         return false;
    60.                 }
    61.                 int index2 = indexmin(index1, n);
    62.                 swap(index1, index2, n);
    63.                 oppositeDirection(index1, n);
    64.                 return true;
    65.         }
    66.         public void pr(int[] n) {
    67.                 for (int i = 0; i < n.length; i++) {
    68.                         System.out.print(n[i] + "  ");
    69.                 }
    70.                 System.out.println();
    71.         }
    72. }
    复制代码
    运行:
      C:at>java S1
    请输入要排列的元素有多少种:3
    1 2 3
    1 3 2
    2 1 3
    2 3 1
    3 1 2
    3 2 1 C:at>java S1
    请输入要排列的元素有多少种:4
    1 2 3 4
    1 2 4 3
    1 3 2 4
    1 3 4 2
    1 4 2 3
    1 4 3 2
    2 1 3 4
    2 1 4 3
    2 3 1 4
    2 3 4 1
    2 4 1 3
    2 4 3 1
    3 1 2 4
    3 1 4 2
    3 2 1 4
    3 2 4 1
    3 4 1 2
    3 4 2 1
    4 1 2 3
    4 1 3 2
    4 2 1 3
    4 2 3 1
    4 3 1 2
    4 3 2 1   
       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/24/000521718.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 04:44 , Processed in 0.301571 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表