1. 用1、2、3、4、5这五个数字,用java写一个main函数,打印出所有不同的排列,如:51234、41235等。 

1. public class
2. static int[] bits = new int[] { 1, 2, 3, 4, 5
3.   
4. /**
5. * @param args
6. */
7. public static void
8. sort("", bits);  
9. }  
10.   
11. private static void sort(String prefix, int[] a) {  
12. if (a.length == 1) {  
13. System.out.println(prefix + a[0]);  
14. }  
15.   
16. for (int i = 0; i < a.length; i++) {  
17. sort(prefix + a[i], copy(a, i));  
18. }  
19. }  
20.   
21. private static int[] copy(int[] a,int
22. int[] b = new int[a.length-1];  
23. System.arraycopy(a, 0, b, 0, index);  
24. System.arraycopy(a, index+1, b, index, a.length-index-1);  
25. return
26. }  
27. }

2. 对第一题增加难度,用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。 

基本思路: 

2-1. 把问题归结为图结构的遍历问题。图遍历思想:实际上6个数字就是六个结点,把六个结点连接成无向连通图,对于每一个结点求这个图形的遍历路径,所有结点的遍历路径就是最后对这6个数字的排列组合结果集。 

2-2. 显然这个结果集还未达到题目的要求。从以下几个方面考虑:                                                 

    2-2-1.   3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。 

    2-2-2.   不能有重复: 考虑到有两个2,明显会存在重复结果,可以把结果集放在TreeSet中过滤重复结果 

    2-2-3.   4不能在第三位: 仍旧在结果集中去除满足此条件的结果。 

采用二维数组定义图结构,最后的代码是: 

1. import
2. import
3.   
4. public class
5.   
6. private String[] b = new String[]{"1", "2", "2", "3", "4", "5"};  
7. private int
8. private boolean[] visited = new boolean[n];  
9. private int[][] a = new int[n][n];  
10. private String result = "";  
11. private TreeSet set = new
12.   
13. public static void
14. new
15. }  
16.   
17. private void
18.   
19. // Initial the map a[][]
20. for (int i = 0; i < n; i++) {  
21. for (int j = 0; j < n; j++) {  
22. if
23. a[i][j] = 0;  
24. } else
25. 1;  
26. }  
27. }  
28. }  
29.   
30. // 3 and 5 can not be the neighbor.
31. a[3][5] = 0;  
32. a[5][3] = 0;  
33.   
34. // Begin to depth search.
35. for (int i = 0; i < n; i++) {  
36. this.depthFirstSearch(i);  
37. }  
38.   
39. // Print result treeset.
40. Iterator it = set.iterator();  
41. while
42. String string = (String) it.next();  
43. // "4" can not be the third position.
44. if (string.indexOf("4") != 2) {  
45. System.out.println(string);  
46. }  
47. }  
48. }  
49.   
50. private void depthFirstSearch(int
51. visited[startIndex] = true;  
52. result = result + b[startIndex];  
53. if
54. // Filt the duplicate value.
55. set.add(result);  
56. }  
57. for(int j = 0; j < n; j++) {  
58. if (a[startIndex][j] == 1 && visited[j] == false) {  
59. depthFirstSearch(j);  
60. } else
61. continue;  
62. }  
63. }  
64.   
65. // restore the result value and visited value after listing a node.
66. 0, result.length() -1);  
67. false;  
68. }  
69. }

3.   递归思想。递归要抓住的关键是:(1)递归出口;(2)地推逐步向出口逼近。 

3-1. 汉诺塔 

  这是递归的超经典的例子,几乎每本程序设计书上谈到递归都会介绍。具体情景不再赘述。以我上述的方法观之: 

    3-1-1. 递归的出口在于disk数为一的时候 

   3-1-2. 向出口逼近:如果不是一,是n ,则我们先挪动上面n-1块disk,等上面挪完,即递归返回的时候,我们挪动最底下的disk. 

  仅仅如此,一个貌似十分复杂的问题就解决了,因为挪动那n-1块disk的时候,会继续向上减少,直到disk的数量为一为止。下面给出代码: 

java 排列组合数计算 java中排列组合库函数_java 排列组合数计算

1. import
2. public class
3. private static final String DISK_B = "diskB";   
4. private static final String DISK_C = "diskC";   
5. private static final String DISK_A = "diskA";   
6. static
7. static
8. static
9. public static void
10. String input=JOptionPane.showInputDialog("please input the number of the disks you want me move.");   
11. int
12. move(num,from,mid,to);   
13. }   
14. private static void move(int
15. if(num==1){   
16. System.out.println("move disk 1 from "+from2+" to "+to2);   
17. }   
18. else
19. move(num-1,from2,to2,mid2);   
20. System.out.println("move disk "+num+" from "+from2+" to "+to2);   
21. move(num-1,mid2,from2,to2);   
22. }   
23. }   
24. }

3-2. 这是一个排列的例子,它所做的工作是将输入的一个字符串中的所有元素进行排序并输出,例如:你给出的参数是"abc" 则程序会输出:

abc 

acb 

bac 

bca 

cab 

cba 

分析: 

    3-2-1. 算法的出口在于:low=high也就是现在给出的排列元素只有一个时; 

    3-2-2. 算法的逼近过程:先确定排列的第一位元素,也就是循环中i所代表的元素,然后low+1开始减少排列元素,如此下去,直到low=high。(暂未调通) 

1. public static void
2. char[] strArray = str.toCharArray();   
3. 0, strArray.length - 1);   
4.   }   
5. public static void permute(char[] list, int low, int
6. int
7. if
8. "";   
9. for (i = 0; i <= high; i++)   
10.   cout += list[i];   
11.   System.out.println(cout);   
12. else
13. for
14. char
15.   list[low] = list[i];   
16.   list[i] = temp;   
17. 1, high);   
18.   temp = list[low];   
19.   list[low] = list[i];   
20.   list[i] = temp;   
21.   }   
22.   }   
23.   }

3-3. 这是一个组合的例子,与上述的例子相似,只是它所做的工作是,输出所给字符串中制定数目的元素的组合种类。 

分析: 

    3-3-1. 程序出口在于n=1,此时只要输出目标数组的所有元素即可 

    3-3-2. 逼近过程,当n>1 的时候,我们先取第一个元素放入目标数组中,然后n-1,如此下去,最后出来。

1. import
2. public class
3. /** 
4. * @param args 
5. */
6. public static void
7. String input = JOptionPane.showInputDialog("please input your String: ");   
8. String numString = JOptionPane.showInputDialog("please input the number of your Combination: ");   
9. int
10. Combine(input, num);   
11. }   
12. private static void Combine(String input, int
13. char[] a = input.toCharArray();   
14. String b = "";   
15. Combine(a, num, b, 0, a.length);   
16. }   
17. private static void Combine(char[] a, int num, String b, int low, int
18. if (num == 0) {   
19. System.out.println(b);   
20. } else
21. for (int
22. b += a[i];   
23. Combine(a, num - 1, b, i+1, a.length);   
24. b=b.substring(0, b.length()-1);   
25. }   
26. }   
27. }   
28. }