关于两个排列的思考


在学校的时候,记得我们的Java程序设计的考试题目是一道编程题,具体的说是满足如下条件的排列:

(1)1,2,2,3,4,5六个数的全排列;

(2)4不能出现在第三位;

(3)3和5不能相邻。

当初,我是用的字符串的操作来做的,结果好像不太合适,最近在CSDN上看到有人也做过。有句话说的好,“你有一个苹果,我有一个苹果,交换后我们每人还是一个苹果;你有一个思想,我有一个思想,交换后我们每人就有两个思想。”,可见交流的重要性,CSDN是个很好的平台,在上面能够跟来自天南地北的人交流,就上面所说的那个问题,很多人都发表了自己的想法,受益匪浅,下面就来分享出我个人的做法,欢迎大家指教!好了,废话不说了!下面就说说我的想法:

    第一步,做个1,2,3,4,5,6六个数的一个全排列。也就是6个数的全排列,总共有720个结果。这步里面有一个技巧,判断前一个数和后一个数是否相等,如果相等,则continue,这样能够减少循环的次数,提高效率。当然,在这步里,顺便考虑了除去了4在第三位的情况。这样就得到了600个数。把得到的结果放入一个TreeSet。

    第二步,从上面得到的结果集中取出3和5不相邻的,放入到一个新的TreeSet中,在放入前,用2替换掉里面的6。这样就得到了最后的结果,也就是198个满足条件的排列。

注意:上面用TreeSet有两个原因,一是可以过滤掉重复的值,二是可以给结果集排序,可以算是两全齐美吧!

下面就是我的程序,欢迎大家指正。

 

view plain
  1. import java.util.Iterator;  
  2. import java.util.Set;  
  3. import java.util.TreeSet;  
  4. public class Combination {  
  5.     public static void main(String[] args) {  
  6.         int[] num = new int[6];  
  7.         for (int i=0; i<num.length; i++) {  
  8.             num[i] = i + 1;  
  9.         }  
  10.           
  11.         long n;  
  12.         Set<Long> result = new TreeSet<Long>();  
  13.         Set<String> result2 = new TreeSet<String>();  
  14.           
  15.         //做1-6六个数字的全排列,过滤掉4在第三位的情况  
  16.         for(int a=0; a<num.length; a++) {  
  17.             for(int b=0; b<num.length; b++) {  
  18.                 //在进入里层循环前判断是否符合条件,可以减少循环次数,  
  19.                 //提交效率  
  20.                 if(a == b) {  
  21.                     continue;  
  22.                 }  
  23.                 for(int c=0; c<num.length; c++) {  
  24.                     if(c == a || c == b || c == 3) {  
  25.                         continue;  
  26.                     }  
  27.                     for(int d=0; d<num.length; d++) {  
  28.                         if(d == a || d == b || d == c) {  
  29.                             continue;  
  30.                         }  
  31.                         for(int e=0; e<num.length; e++) {  
  32.                             if(e == a || e == b || e == c || e == d) {  
  33.                                 continue;  
  34.                             }  
  35.                             for(int f=0; f<num.length; f++) {  
  36.                                 if(f == a || f == b || f == c || f == d || f == e) {  
  37.                                     continue;  
  38.                                 }  
  39.                                 n = num[a] * 100000 + num[b] * 10000 + num[c] * 1000 + num[d] * 100 + num[e] * 10 + num[f];  
  40.                                 result.add(n);  
  41.                             }  
  42.                         }  
  43.                     }  
  44.                 }  
  45.             }  
  46.         }  
  47.           
  48.         //从上面的结果集中找到3和5不相邻的,放入到新的TreeSet中,放入前用2替换掉6  
  49.         String temp;  
  50.         Iterator<Long> iterator = result.iterator();  
  51.         while(iterator.hasNext()) {  
  52.             temp = iterator.next() + "";  
  53.             if(temp.indexOf("35") == -1 && temp.indexOf("53") == -1) {  
  54.                 result2.add(temp.replace("6""2"));  
  55.             }   
  56.         }  
  57.         //打印结果  
  58.         System.out.println("满足条件的记录数(一行显示10个):" + result2.size());  
  59.         int count = 0;  
  60.         for(String s : result2) {  
  61.             System.out.print(s + "    ");  
  62.             count ++;  
  63.             if(count % 10 == 0) {  
  64.                 System.out.println();  
  65.             }  
  66.         }  
  67.     }  
  68. }  

 

下面来说另一个,也是一个排列的,题目的大致意思是:有p、q、r三个数组,对应有0,1两个数字,就是通过给数组赋值(0和1)来打印出一个p、q、r的一个排列。这道题也是CSDN上有人问过的题,大家都爆出了自己的做法,有些直接是赋值做全排列,也有些yo用别的做法的。但是我但是就想到了另外一种做法,下面就说说我的想法。

学计算机的都知道,计算机内部采用的是二进制,所谓的二进制,就是说每个数只有0和1组成。基于这种思想,我就想着可以把题目做个等价变换,也就是说三位0或1构成的一个全排列,更进一步说,就是0-7的二进制表示形式。所以,我就写了下面的程序来实现这个过程。当然了,我的目的是和大家交流,欢迎大家指教。

下面是我的程序:

view plain
  1. public class Main {   
  2.     public static void main(String[] args) {   
  3.         int[] p = new int[8];   
  4.         int[] q = new int[8];   
  5.         int[] r = new int[8];   
  6.            
  7.         //总共有八种0,1组合,也就是0-7的二进制位   
  8.         String temp;   
  9.         int len = 0;   
  10.         for(int i=0; i <8; i++) {               
  11.             temp = Integer.toBinaryString(i);   
  12.             // 在位数小于3的前面补0   
  13.             len = temp.length();   
  14.             for(int j=0; j <3-len; j++) {   
  15.                 temp = "0" + temp;   
  16.             }   
  17.                
  18.             //因为0的ascii编码为48,相减的结果就是数字0-9   
  19.             p[i] = temp.charAt(0) - 48;   
  20.             q[i] = temp.charAt(1) - 48;   
  21.             r[i] = temp.charAt(2) - 48;   
  22.         }   
  23.            
  24.         //输出结果   
  25.         for(int i=0; i <p.length; i++) {   
  26.             System.out.println(p[i] + "" + q[i] + "" + r[i]);   
  27.         }   
  28.     }   
  29.  }   

你可能感兴趣的:(关于两个排列的思考)