消除递归

时间:2011-06-27 16:51:18

标签: java

我刚看了下面这段代码

package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(final String[] args) {

        final int sizeA = 3;
        final int sizeB = 5;

        final List<int[]> combos = getAllCombinations(sizeA-1, sizeB);

        int counter = 1;
        for(final int[] combo : combos) {
            System.out.println("Combination " + counter);
            System.out.println("--------------");
            for(final int value : combo) {
                System.out.print(value + " ");
            }
            System.out.println();
            System.out.println();
            ++counter;
        }

    }

    private static List<int[]> getAllCombinations(final int maxIndex, final int size) {

        if(maxIndex >= size)
            throw new IllegalArgumentException("The maximum index must be smaller than the array size.");

        final List<int[]> result = new ArrayList<int[]>();

        if(maxIndex == 0) {
            final int[] array = new int[size];
            Arrays.fill(array, maxIndex);
            result.add(array);
            return result;
        }

        //We'll create one array for every time the maxIndex can occur while allowing
        //every other index to appear, then create every variation on that array
        //by having every possible head generated recursively
        for(int i = 1; i < size - maxIndex + 1; ++i) {

            //Generating every possible head for the array
            final List<int[]> heads = getAllCombinations(maxIndex - 1, size - i);

            //Combining every head with the tail
            for(final int[] head : heads) {
                final int[] array = new int[size];
                System.arraycopy(head, 0, array, 0, head.length);
                //Filling the tail of the array with i maxIndex values
                for(int j = 1; j <= i; ++j)
                    array[size - j] = maxIndex;
                result.add(array);
            }

        }

        return result;

    }

}

我想知道,如何从此消除递归,以便它返回一个随机组合,而不是所有可能组合的列表?

由于

2 个答案:

答案 0 :(得分:0)

这似乎是家庭作业。没有给你代码,这是一个想法。调用getAllCombinations,将结果存储在List中,并从该列表中的随机索引返回一个值。霍华德在对你的问题的评论中指出,消除递归和返回随机组合是不同的任务。

答案 1 :(得分:0)

如果我正确理解您的代码,您的任务如下:给出长度为'0' .. 'sizeA-1'的数字sizeB的随机组合

  1. 组合已分类
  2. 每个号码至少出现一次
  3. 即。在你的例子中, [0,0,1,2,2]

    如果你想只有一个组合我会建议另一种算法(伪代码):

    • 随机选择升级位置(例如,对于序列[0,0,1,1,2],它将是步骤(1->2)&amp;(3->4)) - 我们需要随机sizeA-1个步骤在sizeB-1位置选择。
    • 从此向量中计算目标组合

    java中的快速实现如下所示

    // Generate list 0,1,2,...,sizeB-2 of possible step-positions 
    List<Integer> steps = new ArrayList<Integer>();
    for (int h = 0; h < sizeB-1; h++) {
        steps.add(h);
    }
    
    // Randomly choose sizeA-1 elements
    Collections.shuffle(steps);
    steps = steps.subList(0, sizeA - 1);
    Collections.sort(steps);
    
    // Build result array
    int[] result = new int[sizeB];
    for (int h = 0, o = 0; h < sizeB; h++) {
        result[h] = o;
        if (o < steps.size() && steps.get(o) == h) {
            o++;
        }
    }
    

    注意:这可以进一步优化 - 第一步生成随机排列,然后将其剥离到所需的大小。因此,只是出于演示目的,算法本身可以按需运行。