我需要帮助通过手头丢弃不需要的排列来使我的排列(重要的,可重复的)大小更小。
当前排列从提供的值中获取全局最小值和最大值。但是,之后的一些排列会被丢弃,因为它们不在所需的范围内。
这个想法是例如需要排列的3个数字。例如:1-3,8-10和5-15。当前代码将创建1-15的排列,即使稍后将丢弃4-7的值。
不幸的是,在某些情况下,不可能在Java中创建足够大的数组来包含排列结果。
在计算排列之前,将此排列更改为仅包括必要值,将会有所帮助。
PermutationCore:
public class PermutationCore {
private String[] a;
private int n;
public PermutationCore(String[] arrayOfPossibilities, int lengthOfPermutation) {
this.a = arrayOfPossibilities;
this.n = lengthOfPermutation;
}
public String[][] getVariations() {
int l = a.length;
int permutations = (int) Math.pow(l, n);
Co.println("Permutation array size: " + permutations);
String[][] table = new String[permutations][n];
for (int x = 0; x < n; x++) {
int t2 = (int) Math.pow(l, x);
for (int p1 = 0; p1 < permutations;) {
for (int al = 0; al < l; al++) {
for (int p2 = 0; p2 < t2; p2++) {
table[p1][x] = a[al];
p1++;
}
}
}
}
return table;
}
}
置换
public class Permutation {
private ArrayList<Iteration> listOfIteration = new ArrayList<Iteration>();
private boolean prepared;
private PermutationCore permutationCore;
private int min = Integer.MAX_VALUE;
private int max = Integer.MIN_VALUE;
private int count = 0;
private String[][] arrayOfStringResults;
public void addIteration(Iteration iteration){
if (prepared){throw new IllegalStateException("Permuation is already prepared. Create a new instance to add new items");}
this.listOfIteration.add(iteration);
}
public void prepare(){
String[] arrayOfString;
for (Iteration iteration : listOfIteration){
if (iteration.end > max){max = iteration.end;}
if (iteration.start < min){min = iteration.start;}
}
arrayOfString = new String[max-min+1];
for (int i=0; i<arrayOfString.length; i++){
arrayOfString[i] = String.valueOf(min+i);
}
permutationCore = new PermutationCore(arrayOfString, listOfIteration.size());
prepared = true;
// Co.println("Min/max: " + min + "," + max);
arrayOfStringResults = permutationCore.getVariations();
// ArrayTools.sort2DStringArray(arrayOfStringResults);
}
public boolean iterate(){
LABEL_ITERATE_LOOP: {
int i=0;
if (count == arrayOfStringResults.length){
return false;
}
for (Iteration iteration : listOfIteration){
int currentValue = Integer.valueOf(arrayOfStringResults[count][i]);
if (currentValue > iteration.end || currentValue < iteration.start){
//Co.println("Failed at: " + iteration.start + "," + iteration.end + " / " + currentValue);
count++;
break LABEL_ITERATE_LOOP;
}
iteration.current = currentValue;
i++;
}
count++;
}
return true;
}
public Iteration getIteration(Object request) {
for (Iteration iteration : listOfIteration){
if (iteration.request == request){
return iteration;
}
}
return null;
}
public ArrayList<Iteration> getListOfIterations(){
return listOfIteration;
}
public static class Iteration{
private int start;
private int end;
private int current;
private Object request;
public Iteration(int start, int end, Object request){
this.start = start;
this.end = end;
this.request = request;
}
public double getCurrentValue(){
return this.current;
}
public Object getRequest(){
return this.request;
}
}
}
答案 0 :(得分:3)
这个问题是将k数从0到(n-1)排列,然后打印[n]而不是n。 :)这就是你可以做的,减少迭代。
另一种方法是使用介于0到n!-1之间的数字,找出当前的排列,然后打印出来。虽然这是一种较慢的方法,但以这种格式恢复操作会更快 - 我们可以快速打印第k个排列。
让我们说数字是:1,2,3,4。总共有4个!置换= 24,可能。要打印第15个(从零开始)排列,这就是我们的工作:
n = 4 a = 1 2 3 4 将15除以(n-1)!
我们得到15/6 = 2,提醒= 3。
所以排列以[2] = 3开始。
a = 1 2 4 接受提示,除以(n-2)!
我们得到3/2 = 1,提醒= 1。
所以排列现在是排列,a [1] = 3,2
a = 1 4 接受提示,除以(n-1)!
我们得到1/1 = 1,提醒= 0
所以排列现在是排列,a [1] = 3,2,4。
直到提醒为零。打印[0] = 3,2,4,1。
^这是生成任何系列的第k个排列的最有效方法。
您可以使用BigInteger数学来非常有效地执行此方法。