如何从给定数组中生成所有可能的组合

时间:2014-08-05 03:22:41

标签: java arrays combinations

由于人们感到困惑,我用代码再次改写我的问题。

我想让d在这里动态化,即我希望能够在不事先知道d的值的情况下生成所有可能的数组值组合。

现在,我使用if-clause,我只能支持1到4的d。

if( d == 4 )
{
        for( double i = min ; i <= max ; i = i+ sz )
        {
            for( double j = min ; j <= max ; j = j + sz )
            {
                for( double h = min ; h<=max ; h = h + sz )
                {
                    for( double p = min ; p<=max ; p = p + sz )
                    {
                        double[] att = {i, j, h, p};
                    }
                }
            }
        }
}

if( d == 3 )
{
    for( double i = min ; i <= max ; i = i+ sz )
    {
        for( double j = min ; j <= max ; j = j + sz )
        {
            for( double h = min ; h<=max ; h = h + sz )
            {   
                double[] att = {i, j, h};
            }
        }
    }   
}

if( d == 2 )
{
    for( double i = min ; i <= max ; i = i+ sz )
    {
        for( double j = min ; j <= max ; j = j + sz )
        {
            double[] att = {i, j};
        }
    }   
}

if( d == 1 )
{
    for( double i = min ; i <= max ; i = i+ sz )
    {
        double[] att = {i, j};
    }   
}

正如你所看到的,如果我之前不知道d的价值,我就无法做到。

还有一件事,我不想使用任何模板或预定义的类,如List等。

4 个答案:

答案 0 :(得分:1)

这是执行您想要的代码:

private static int[][] getPossibleValues(final int[] from, final int[] to, final int step) {
    final int width = from.length;
    final int[][] values = new int[width][];

    for (int idx = 0; idx < width; idx++) {
        values[idx] = makeSequence(from[idx], to[idx], step);
    }

    return values;
}

@SuppressWarnings("boxing")
private static List<Integer[]> getPossibleCombinations(final int[][] values, final Stack<Integer> fixed) {
    final int width = fixed.size();
    if (width == values.length) {
        // System.out.println(fixed);
        return Collections.singletonList(fixed.toArray(new Integer[0]));
    }

    final List<Integer[]> res = new ArrayList<>();
    for (int i = 0; i < values[width].length; i++) {
        fixed.push(values[width][i]);
        res.addAll(getPossibleCombinations(values, fixed));
        fixed.pop();
    }

    return res;
}

private static int[] makeSequence(final int from, final int to, final int step) {
    if (((to < from) && (step > 0)) || ((to > from) && (step < 0))) {
        return new int[] { from };
    }

    final int len = ((to - from) / step) + 1;
    final int[] res = new int[len];

    int cur = from;
    for (int i = 0; i < len; i++) {
        res[i] = cur;
        cur += step;
    }

    return res;
}

您可以按如下方式使用它:

public static void main(final String[] args) {
    final int[] from = new int[] { 0, 0, 0 };
    final int[] to = new int[] { 1, 1, 1 };
    final int step = 1;

    for (final Integer[] ints : getPossibleCombinations(getPossibleValues(from, to, step), new Stack<Integer>())) {
        System.out.println(Arrays.asList(ints));
    }
}

输出:

[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]

奖金,检查参数是否合理:

@SuppressWarnings("boxing")
private static void checkArgs(final List<Integer> init, final List<Integer> target, final int step) {
    if (init.size() != target.size()) {
        throw new IllegalArgumentException("Initial and target arrays must be of the same size.");
    }

    if (step == 0) {
        throw new IllegalArgumentException("The step shouldn't be 0.");
    }

    final boolean increment = step > 0;
    for (int idx = 0; idx < init.size(); idx++) {
        if ((increment && (target.get(idx) < init.get(idx))) || (!increment && (target.get(idx) > init.get(idx)))) {
            throw new IllegalArgumentException(
                                                String
                                                    .format(
                                                            "Inconsistent arguments for elements at the index %s: %s cannot reach %s with increments of %s.",
                                                            idx,
                                                            init.get(idx),
                                                            target.get(idx),
                                                            step));
        }
    }
}

答案 1 :(得分:1)

你可以试试这个

static void moves(ArrayList<Integer> prefix, ArrayList<ArrayList<Integer>> result, int min, int max, int stepSize, int maxLength) {
  if(prefix.size() == maxLength) result.add(prefix);
  else {
    for(int i = min; i <= max; i += stepSize) {
      ArrayList<Integer> newPrefix = new ArrayList<Integer>(prefix);
      newPrefix.add(i);
      moves(newPrefix, result, min, max, stepSize, maxLength);
    }
  }
}

static ArrayList<ArrayList<Integer>> moves(int min, int max, int stepSize, int maxLength) {
  ArrayList<ArrayList<Integer>> result = new ArrayList<>();
  moves(new ArrayList<Integer>(), result, min, max, stepSize, maxLength);
  return result;
}

然后你可以用例如moves(0, 50, 5, 2);

答案 2 :(得分:0)

好的,这是一个很好的思考问题让我花了一些时间来解决问题 在没有给出答案的情况下,很难引导你完成它。

一般人们都会问“你试过什么代码?”。您应该能够编写一些代码来为数组的一个值进行排列,然后从那里开始工作。

从一些代码开始。

perm(int[] start, int step, int[] max, int[] min)

这是方法签名应该是什么样的?你有一个从一开始的数组。你为每一步“跳跃”多远,并且数组的每个索引都有一个需要考虑的最大值和最小值。

我开始创建一个int[] copy起始数组。当我们递增下一个索引值时,我们需要复制原始值。

增加数组中的第一个元素很容易。 copy[0] += step;。现在我们需要做一些检查。如果该值大于最大值或小于最小值,我们需要重置该值(copy[position] = start[position];)并按步骤递增下一个索引。
然后你会注意到一些循环逻辑的代码。我们还需要检查我们增加的值是否在其范围内。所以这是一个在循环中编写代码的问题,它记录了它正在处理的数组中的位置。

从可以满足您需要的小块代码开始,逐步完成数组的处理并处理边缘情况(当它超过最大值时,超过最小值,当您完成数组处理时)。

很高兴回答进一步的问题,但你需要问一下你所拥有的代码示例,所以我不觉得我在为你编写代码。

答案 3 :(得分:0)

以下尝试概括嵌套循环的概念:

static int[][] permute(int[] initial, int[]min,int[] max,int step){//input parameters
    int dim = initial.length;                     //assume all arrays are equal, should probably check though
    int[] start = new int[dim];                   //array for storing the starting value of each loop
    for (int i = 0; i < dim; i++) {
        start[i] = min[i]+(initial[i]-min[i])%step;//finds the smallest value within the given bounds
    }
    int[] steps = new int[dim];                   //number of iterations of each loop
    int totalElements=1;                          //total elments in result
    for (int i = 0; i < dim; i++) {
        steps[i] = (max[i]-start[i])/step+1;      //computes the number of steps in each dimension on [min,max] inclusive
        totalElements*=steps[i];
    }

    int[][] results = new int[totalElements][];//for storing results
    for (int i = 0; i < totalElements; i++) {
        results[i]= new int[dim];
        int temp = i;
        for (int j = 0; j < dim; j++) {
            results[i][j] = start[j] + ((temp%steps[j]) * step);//clever method for looping through the array sand storing the result
            temp/=steps[j];
        }
    }
    return results;
}

运行

int[][] result = permute(new int[]{10,5}, new int[]{0,0}, new int[]{50,50}, 5);
for (int[] i : result)
    System.out.println(Arrays.toString(i));

产生

[0, 0]
[5, 0]
[10, 0]
[15, 0]
[20, 0]
[25, 0]
[30, 0]
[35, 0]
[40, 0]
[45, 0]
[50, 0]
[0, 5]
[5, 5]
[10, 5]
[15, 5]
[20, 5]
[25, 5]
[30, 5]
[35, 5]
[40, 5]
[45, 5]
[50, 5]
[0, 10]
[5, 10]
[10, 10]
[15, 10]
[20, 10]
[25, 10]
[30, 10]
[35, 10]
[40, 10]
[45, 10]
[50, 10]
[0, 15]
[5, 15]
[10, 15]
[15, 15]
[20, 15]
[25, 15]
[30, 15]
[35, 15]
[40, 15]
[45, 15]
[50, 15]
[0, 20]
[5, 20]
[10, 20]
[15, 20]
[20, 20]
[25, 20]
[30, 20]
[35, 20]
[40, 20]
[45, 20]
[50, 20]
[0, 25]
[5, 25]
[10, 25]
[15, 25]
[20, 25]
[25, 25]
[30, 25]
[35, 25]
[40, 25]
[45, 25]
[50, 25]
[0, 30]
[5, 30]
[10, 30]
[15, 30]
[20, 30]
[25, 30]
[30, 30]
[35, 30]
[40, 30]
[45, 30]
[50, 30]
[0, 35]
[5, 35]
[10, 35]
[15, 35]
[20, 35]
[25, 35]
[30, 35]
[35, 35]
[40, 35]
[45, 35]
[50, 35]
[0, 40]
[5, 40]
[10, 40]
[15, 40]
[20, 40]
[25, 40]
[30, 40]
[35, 40]
[40, 40]
[45, 40]
[50, 40]
[0, 45]
[5, 45]
[10, 45]
[15, 45]
[20, 45]
[25, 45]
[30, 45]
[35, 45]
[40, 45]
[45, 45]
[50, 45]
[0, 50]
[5, 50]
[10, 50]
[15, 50]
[20, 50]
[25, 50]
[30, 50]
[35, 50]
[40, 50]
[45, 50]
[50, 50]