1 5 package org.h2.util; 6 7 import org.h2.message.Message; 8 9 10 15 public class Permutations { 16 17 private Object [] in; 18 private Object [] out; 19 private int n, m; 20 private int[] index; 21 private boolean hasNext = true; 22 23 public Permutations(Object [] in, Object [] out) { 24 this(in, out, in.length); 25 } 26 27 public Permutations(Object [] in, Object [] out, int m) { 28 this.n = in.length; 29 this.m = m; 30 if (n < m || m < 0) { 31 throw Message.getInternalError("n < m or m < 0"); 32 } 33 this.in = in; 34 this.out = out; 35 index = new int[n]; 36 for (int i = 0; i < n; i++) { 37 index[i] = i; 38 } 39 40 reverseAfter(m - 1); 43 } 44 45 57 private void moveIndex() { 58 int i = rightmostDip(); 60 if (i < 0) { 61 hasNext = false; 62 return; 63 } 64 65 int leastToRightIndex = i + 1; 67 for (int j = i + 2; j < n; j++) { 68 if (index[j] < index[leastToRightIndex] && index[j] > index[i]) { 69 leastToRightIndex = j; 70 } 71 } 72 73 int t = index[i]; 75 index[i] = index[leastToRightIndex]; 76 index[leastToRightIndex] = t; 77 78 if (m - 1 > i) { 79 reverseAfter(i); 81 82 reverseAfter(m - 1); 84 } 85 } 86 87 91 private int rightmostDip() { 92 for (int i = n - 2; i >= 0; i--) { 93 if (index[i] < index[i + 1]) { 94 return i; 95 } 96 } 97 return -1; 98 } 99 100 103 private void reverseAfter(int i) { 104 int start = i + 1; 105 int end = n - 1; 106 while (start < end) { 107 int t = index[start]; 108 index[start] = index[end]; 109 index[end] = t; 110 start++; 111 end--; 112 } 113 } 114 115 120 public boolean next() { 121 if (!hasNext) { 122 return false; 123 } 124 for (int i = 0; i < m; i++) { 125 out[i] = in[index[i]]; 126 } 127 moveIndex(); 128 return true; 129 } 130 131 } 132 | Popular Tags |