Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何递归地获取Java中的所有组合?_Java_Recursion - Fatal编程技术网

如何递归地获取Java中的所有组合?

如何递归地获取Java中的所有组合?,java,recursion,Java,Recursion,在Java中,使用递归函数从多组候选元素中获取所有元素组合的最佳方法是什么 通常,候选集的数量是未定义的,因此递归解决方案似乎适合于此任务。作为给定候选集的示例 [1,2] [3,4] [5,6,7] 应该得到12个组合: [1,3,5] [2,3,5] [1,4,5] [2,4,5] [1,3,6] [2,3,6] [1,4,6] [2,4,6] [1,3,7] [2,3,7] [1,4,7] [2,4,7] 候选集表示为类型列表的列表:List您不需要递归。只需使用集合列表的大小,然

在Java中,使用递归函数从多组候选元素中获取所有元素组合的最佳方法是什么

通常,候选集的数量是未定义的,因此递归解决方案似乎适合于此任务。作为给定候选集的示例

[1,2]
[3,4]
[5,6,7]
应该得到12个组合:

[1,3,5] [2,3,5] 
[1,4,5] [2,4,5]
[1,3,6] [2,3,6]
[1,4,6] [2,4,6]
[1,3,7] [2,3,7]
[1,4,7] [2,4,7] 

候选集表示为类型列表的列表:List

您不需要递归。只需使用集合列表的大小,然后使用每个集合的大小。您可以保留结果,以便添加更多的元素,以防将来有更多的集合要混合,以防这是您需要的。

组合的总数是候选集合大小的乘积。每个结果集的大小等于候选集的数量

解决方案不需要递归。只需检查每个候选集。在本例中,第一个有两个值,1和2。前6个结果集(其中一半)的第一个值为1。下半场得6分

在下一个候选集上,有两个值,3和4。但这一次,将他们分成3人一组,而不是6人一组。前3个结果集得到3,下3个结果集得到4,下3个结果集得到3,依此类推


下一个候选集有三个值:5、6和7。现在将旋转为每个结果集指定的值(旋转每个1个指定)。如果有更多候选集或其中的值数量不同,则在旋转到下一个值之前指定的值数量将发生变化。但是你可以通过编程来解决这个问题。

我几年前也遇到过同样的问题。我用一个里程表遍历结果列表,解决了这个问题

里程表中的车轮数是输入组数。每个轮子上的数字都是相应组的成员。要获得下一个排列,请滚动最右侧的里程表轮。如果它一直转过来,把它滚到左边,等等

例如:

Wheel 0 values: [1,2]
Wheel 1 values: [3,4]
Wheel 2 values: [5,6,7]
从里程表读数(1,3,5)开始。前进到(1,3,6)、(1,3,7)。然后将下一个轮子也滚动到(1,4,5)、(1,4,6)和(1,4,7)。继续

里程表车轮作为索引

或者,您可以将控制盘表示为相应列表中的索引

Wheel 0 values: [0,1]
Wheel 1 values: [0,1]
Wheel 2 values: [0,1,2]
从里程表读数(0,0,0)开始。前进到(0,0,1)、(0,0,2)。然后将下一个轮子也滚动到(0,1,0)、(0,1,1)和(0,1,2)。继续。对于每个读数,使用里程表轮读数作为输入列表的索引,转换为结果列表

作为迭代器的里程表轮子


作为另一种选择,您可以将控制盘表示为输入集合中的迭代器。这比前两种方法更一般。即使索引无法访问输入集合,它也可以工作。而且它是可伸缩的。这就是我几年前使用的方法。

谢谢大家的回复

安迪·托马斯,关于里程表的想法很有趣。我稍后会试试看。目前,我已经按照云计算的建议实现了它

以下是我得到的(对于整数项;如果需要可以推广):

公共列表组合(候选列表){
列表结果=新建ArrayList();
//计算结果大小
int size=1;
(候选人名单集:候选人)
size*=候选集size();
//产生结果
对于(int i=0;i
这是另一个版本(里程表,安迪·托马斯建议的)

import java.util.ArrayList;
导入java.util.Iterator;
导入java.util.List;
公营里程表{
私家车{
列表值;
int-idx=0;
/**
*从值列表创建里程表轮子
*@param v
*/
受保护车轮(列表v){
如果(v==null)抛出新的NullPointerException(“无法创建具有null值的Wheel.class实例”);
如果(v.isEmpty())抛出新的IllegalArgumentException(“无法创建没有值的Wheel.class实例”);
这个值=v;
}
/**
*获取车轮值
*@返回
*/
保护T值(){
返回值.get(idx);
}
/**
*将里程表轮切换一步
*@return TRUE-如果一个轮子已完成整个循环并切换到第一项
*/
受保护的布尔型next(){
如果(idx>=values.size()-1){
idx=0;
返回true;
}否则{
idx++;
返回false;
}
}
}
/**
*车轮列表
*/
private List wheels=new ArrayList();
/**
*从多个值列表中创建里程表
*(每个列表是一个里程表车轮的值列表)
*@param值
*/
公共里程表(列表值){
对于(列表v:值)
车轮。添加(新车轮(v));
}
/**
*获取里程表值
*@返回
*/
公共列表get(){
列表结果=新的Arr
public List<List<Integer>> makeCombinations(List<List<Integer>> candidates) {

    List<List<Integer>> result = new ArrayList<List<Integer>>();

    // calculate result size
    int size = 1;
    for (List<Integer> candidateSet : candidates)
        size *= candidateSet.size();

    // make result
    for (int i = 0; i < size; i++)
        result.add(new ArrayList<Integer>());

    // fill result
    int pos = 1;
    for (List<Integer> candidateSet : candidates)
        fillPosition(candidateSet, result, countRepeats(candidates, pos++));

    // return
    return result;
}

public int countRepeats(List<List<Integer>> candidates, int pos) {

    int repeats = 1;
    for (int i = pos; i < candidates.size(); i++)
        repeats *= candidates.get(i).size();
    return repeats;
}

public void fillPosition(   List<Integer>      candidateSet, 
                            List<List<Integer>>      result, 
                            int                     repeats) {

    int idx = 0;
    while (idx < result.size()) {
        for (int item : candidateSet) {
            for (int i = 0; i < repeats; i++) {
                result.get(idx++).add(item);
            }
        }
    }
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Odometer<T> implements Iterable<List<T>> {

    private class Wheel {
        List<T> values;
        int         idx = 0;

        /**
         * Create an odometer wheel from list of values
         * @param v
         */
        protected Wheel (List<T> v) {
            if (v == null)   throw new NullPointerException("can't create an instance of Wheel.class with null values");
            if (v.isEmpty()) throw new IllegalArgumentException("can't create an instance of Wheel.class with no values");
            this.values = v;
        }

        /**
         * Get wheel value
         * @return
         */
        protected T value() {
            return values.get(idx);
        }

        /**
         * switch an odometer wheel one step 
         * @return TRUE - if a wheel have made full cycle and have switched to first item
         */
        protected boolean next() {
            if (idx >= values.size() - 1) {
                idx = 0; 
                return true;
            } else {
                idx++;
                return false;
            }

        }
    }

    /**
     * list of wheels
     */
    private List<Wheel> wheels = new ArrayList<Wheel>();

    /**
     * Create an odometer from several lists of values 
     * (each List<T> is a list of values for one odometer wheel)
     * @param values
     */
    public Odometer(List<List<T>> values) {
        for (List<T> v : values)
            wheels.add(new Wheel(v));
    }

    /**
     * Get odometer value
     * @return
     */
    public List<T> get() {
        List<T> result = new ArrayList<T>();
        for (Wheel wheel : wheels) {
            result.add(wheel.value());
        }
        return result;
    }

    /**
     * Switch to next value
     * @return TRUE if full cycle is finished
     */
    public boolean next() {
        for (int i = wheels.size() - 1; i >= 0; i--)
            if (!wheels.get(i).next()) return false;
        return true;
    }

    /**
     * Reset odometer
     */
    public void reset() {
        for (Wheel wheel : wheels)
            wheel.idx = 0;
    }

    /**
     * Iterator
     */
    @Override
    public Iterator<List<T>> iterator() {
        reset();
        Iterator<List<T>> it = new Iterator<List<T>>() {
            private boolean last = false;

            @Override
            public boolean hasNext() {
                return !last;
            }
            @Override
            public List<T> next() {
                List<T> result = get();
                last = Odometer.this.next();
                return result;
            }
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
        return it;  
    }

    public static void main(String [] args) {
        List<Integer> l1 = new ArrayList<Integer>(); l1.add(1); l1.add(2);
        List<Integer> l2 = new ArrayList<Integer>(); l2.add(3); l2.add(4); l2.add(5);
        List<Integer> l3 = new ArrayList<Integer>(); l3.add(6); l3.add(7);
        List<List<Integer>> list = new ArrayList<List<Integer>>(); list.add(l1); list.add(l2); list.add(l3); 
        Odometer<Integer> odometer = new Odometer<Integer>(list);
        for (List<Integer> value : odometer) {
            System.out.println(value);
        }
    }
}