一、递归的实现排练与组合
全排列:
public static void recursive(char[] test_array, int start, int end) { if (start == end) { for (int i = 0; i <= end; i++) { System.out.print(test_array[i] + " "); } System.out.println(); } else { for (int j = start; j <= end; j++) { char temp = test_array[start]; test_array[start] = test_array[j]; test_array[j] = temp; recursive(test_array, start + 1, end); temp = test_array[start]; test_array[start] = test_array[j]; test_array[j] = temp; } } }
组合:这个组合是从后向前的i>=m
如果从前向后应该是的i<=m
static void combine( int a[],int n,int m,int b[] ) { for(int i=n; i>=m; i--) { b[m-1] = a[i-1]; if (m > 1) combine(a,i-1,m-1,b); else { System.out.println(Arrays.toString(b)); } } }
二、非递归方法
排列:1.首先排序递增,那么这是最小的字典顺序。一直到递减则是最后一个位置
2.接着倒叙查找如果有大于前一个的位置(这说明有下一个排列)
3.在上个可能的位置后面查找可能有最小的大于当前的值(这个是存在排列的一个最小的序)
4.交换位置后一位后面是(递减的,要反转变成递增的)这样得到新列的最小序
5.如果全部变成了递增额则排列结束了
public static void main(String[] args) { // TODO 自动生成方法存根 WordBook a = new WordBook(); Scanner input = new Scanner(System.in); System.out.print("请输入要排列的元素有多少种:"); int count = input.nextInt(); int[] p = new int[count]; for (int i = 1; i <= p.length; i++) { p[i - 1] = i; } boolean con; long start=System.currentTimeMillis(); do { a.pr(p);// 输出排列p con = a.next(p);// 求出按字典序排列的下一个排列p } while (con); System.out.println(System.currentTimeMillis()-start); } public int indexof(int[] n) { int index = -1; for (int i = n.length - 1; i >= 1; i--) { if (n[i - 1] < n[i]) { index = i - 1; break; } } return index; } public int indexmin(int ini, int[] n) { int index = n.length - 1; int min = n[ini + 1]; for (int i = ini + 1; i < n.length; i++) { if (n[i] <= min && n[i] > n[ini]) { min = n[i]; index = i; } } return index; } public void swap(int index1, int index2, int[] n) { int temp; temp = n[index1]; n[index1] = n[index2]; n[index2] = temp; } public void oppositeDirection(int index1, int[] n) { for (int i = index1 + 1, j = n.length - 1, k = 0, temp; k <= (n.length - i) / 2; i++, j--, k++) { temp = n[i]; n[i] = n[j]; n[j] = temp; } } public boolean next(int[] n) { int index1 = indexof(n); if (index1 == -1) { return false; } int index2 = indexmin(index1, n); swap(index1, index2, n); oppositeDirection(index1, n); return true; } public void pr(int[] n) { for (int i = 0; i < n.length; i++) { System.out.print(n[i] + " "); } System.out.println(); }
组合:网上找的那个10排列的
//按照网上的10转换 //输出有10的位置第一次位置 //然后调整为01 //10左边的移动到左边 static void combine2(int[]a,int n,int m,int[] b){ for(int i=0;i<m;i++) b[i]=1; do{ printArray(b,a); }while(getFirstFlage(b,n,m)!=-1); } static int getFirstFlage(int[]b,int n,int m){ int count=0; for(int i=0;i<n-1;i++){ if(b[i]==1&&b[i+1]==0){ //交换位置 b[i]=0; b[i+1]=1; //移动 for(int j=0;j<count;j++){ b[j]=1; } for(int k=count;k<i;k++) b[k]=0; // System.out.println(count+"=="+Arrays.toString(b)); return i; }else if(b[i]==1){ count++; } } return -1; } static void printArray(int[]b,int[]a){ for(int i=0;i<b.length;i++){ if(b[i]==1) System.out.print(a[i]+" "); } System.out.println(); } public static void main(String[] args) { int[] a=new int[]{1,2,3,4,5,6,7,8}; int[] b=new int[8]; combine2(a,a.length,3,b); //combine(a,a.length,2,b); //System.out.println("总的个数:"+k); }