Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.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 - Fatal编程技术网

使用Java从每个列表中选择一个单词,而不使用递归,从列表中查找所有单词的组合

使用Java从每个列表中选择一个单词,而不使用递归,从列表中查找所有单词的组合,java,Java,鉴于: [[“快”、“懒”]、[“棕色”、“灰色”]、[“狐狸”、“狗”] 使用Java从每个列表中只选择一个单词来查找所有组合 解决方案应适用于任何此类列表 可能的最佳时间复杂度 不使用递归 我的解决方案: public static <T> Set<List<T>> getCombinations(List<List<T>> lists) { Set<List<T>> combinations =

鉴于:
[[“快”、“懒”]、[“棕色”、“灰色”]、[“狐狸”、“狗”]

使用Java从每个列表中只选择一个单词来查找所有组合

  • 解决方案应适用于任何此类列表
  • 可能的最佳时间复杂度
  • 不使用递归
我的解决方案:

public static <T> Set<List<T>> getCombinations(List<List<T>> lists) {
    Set<List<T>> combinations = new HashSet<List<T>>();
    Set<List<T>> newCombinations;

    int index = 0;

    // extract each of the integers in the first list
    // and add each to ints as a new list
    for(T i: lists.get(0)) {
        List<T> newList = new ArrayList<T>();
        newList.add(i);
        combinations.add(newList);
    }
    index++;
    while(index < lists.size()) {
        List<T> nextList = lists.get(index);
        newCombinations = new HashSet<List<T>>();
        for(List<T> first: combinations) {
            for(T second: nextList) {
                List<T> newList = new ArrayList<T>();
                newList.addAll(first);
                newList.add(second);
                newCombinations.add(newList);
            }
        }
        combinations = newCombinations;

        index++;
    }

    return combinations;
}
publicstaticset-getcombines(列表){
集合组合=新的HashSet();
设置新的二进制文件;
int指数=0;
//提取第一个列表中的每个整数
//并将其作为新列表添加到ints
for(ti:list.get(0)){
List newList=newarraylist();
新列表。添加(i);
组合。添加(新列表);
}
索引++;
while(索引
这里有两种不同的解决方案。对于这两种情况,输入都进行了扩展,以表明它可以处理每个子列表中不同数量的值

第一个解决方案计算组合的总数,然后迭代每个“编号”组合,从每个子列表中计算要使用的值。仅当子列表基于数组时才应使用此解决方案,因为它使用
get(int index)
,否则性能将降低

第二种解决方案是尽可能开放的,即外部“列表”可以是任何
集合
,“子列表”可以是任何类型的
Iterable
。它会产生更多的垃圾,因为它必须不断地重新创建迭代器,但这不应该是一个问题(现在GC很好)

对于变化,这两种解决方案以不同的顺序生成组合,但它们都可以通过另一种方式进行更改

解决方案1

public static <T> List<List<T>> getCombinations(List<List<T>> valueSetList) {
    int comboCount = 1;
    for (List<T> valueSet : valueSetList)
        comboCount = Math.multiplyExact(comboCount, valueSet.size()); // Fail if overflow
    List<List<T>> combinations = new ArrayList<>(comboCount);
    for (int comboNumber = 0; comboNumber < comboCount; comboNumber++) {
        List<T> combination = new ArrayList<>(valueSetList.size());
        int remain = comboNumber;
        for (List<T> valueSet : valueSetList) {
            combination.add(valueSet.get(remain % valueSet.size()));
            remain /= valueSet.size();
        }
        combinations.add(combination);
    }
    return combinations;
}
输出1

public static <T> List<List<T>> getCombinations(List<List<T>> valueSetList) {
    int comboCount = 1;
    for (List<T> valueSet : valueSetList)
        comboCount = Math.multiplyExact(comboCount, valueSet.size()); // Fail if overflow
    List<List<T>> combinations = new ArrayList<>(comboCount);
    for (int comboNumber = 0; comboNumber < comboCount; comboNumber++) {
        List<T> combination = new ArrayList<>(valueSetList.size());
        int remain = comboNumber;
        for (List<T> valueSet : valueSetList) {
            combination.add(valueSet.get(remain % valueSet.size()));
            remain /= valueSet.size();
        }
        combinations.add(combination);
    }
    return combinations;
}
[快,布朗,福克斯]
[懒,棕色,狐狸]
[快,格雷,狐狸]
[懒,灰,狐狸]
[快,黑,狐狸]
[懒,黑,狐狸]
[快,瑞德,狐狸]
[懒,红,狐狸]
[快,布朗,狗]
[懒,棕色,狗]
[快,格雷,狗]
[懒,灰,狗]
[快,黑,狗]
[懒,黑,狗]
[快,瑞德,狗]
[懒,红,狗]
[快,布朗,狼]
[懒,布朗,狼]
[快,灰色,狼]
[懒,灰,狼]
[快,黑,狼]
[懒,黑,狼]
[快,红,狼]
[懒,红,狼]
输出2

@SuppressWarnings("unchecked")
public static <T> List<List<T>> getCombinations(Collection<? extends Iterable<T>> valueSetCollection) {
    Iterable<T>[] valueSets = new Iterable[valueSetCollection.size()];
    Iterator<T>[] valueIters  = new Iterator[valueSetCollection.size()];
    T[] values = (T[]) new Object[valueSetCollection.size()];
    int i = 0;
    for (Iterable<T> valueSet : valueSetCollection) {
        valueSets[i] = valueSet; // Copy to array for fast index lookup
        valueIters[i] = valueSet.iterator();
        values[i] = valueIters[i].next(); // Fail if a wordSet is empty
        i++;
    }
    List<List<T>> combinations = new ArrayList<>();
    NEXT_COMBO: for (;;) {
        combinations.add(Arrays.asList(values.clone()));
        for (i = values.length - 1; i >= 0; i--) {
            if (valueIters[i].hasNext()) {
                values[i] = valueIters[i].next();
                continue NEXT_COMBO;
            }
            valueIters[i] = valueSets[i].iterator();
            values[i] = valueIters[i].next();
        }
        return combinations;
    }
}
[快,布朗,福克斯]
[快,布朗,狗]
[快,布朗,狼]
[快,格雷,狐狸]
[快,格雷,狗]
[快,灰色,狼]
[快,黑,狐狸]
[快,黑,狗]
[快,黑,狼]
[快,瑞德,狐狸]
[快,瑞德,狗]
[快,红,狼]
[懒,棕色,狐狸]
[懒,棕色,狗]
[懒,布朗,狼]
[懒,灰,狐狸]
[懒,灰,狗]
[懒,灰,狼]
[懒,黑,狐狸]
[懒,黑,狗]
[懒,黑,狼]
[懒,红,狐狸]
[懒,红,狗]
[懒,红,狼]
试试这个

public static <T> Set<List<T>> getCombinations(List<List<T>> lists) {
    int max = 1;
    for (List<T> list : lists)
        max *= list.size();
    Set<List<T>> result = new HashSet<>(max);
    for (int i = 0; i < max; ++i) {
        List<T> newSublist = new ArrayList<>();
        int n = i;
        for (List<T> list : lists) {
            int size = list.size();
            newSublist.add(list.get(n % size));
            n /= size;
        }
        result.add(newSublist);
    }
    return result;
}
publicstaticset-getcombines(列表){
int max=1;
用于(列表:列表)
max*=list.size();
设置结果=新哈希集(最大值);
对于(int i=0;i
您能列出预期的输出吗。那会很有帮助的。我们不想直接从你的作业中看到问题,我们已经完成了我们的任务。你在挣扎什么?你尝试过什么吗?@J.Knight我想在不使用递归的情况下提高时间复杂度。这可能吗?我不相信不使用递归这是可能的,但这应该可以简化,只需对内部和外部列表运行一个嵌套的for循环,然后每次将结果的组合添加到HashSet中,它将不允许任何重复。我可以问一下,当您实际处理字符串时,为什么您的解决方案是指整数吗?很好的工作伙伴:)@Andreas解决方案1的时间复杂度是O(n^2)。它比我的好吗?@sach20我不知道它是O(n^2),但我也不知道你对
n
的定义是什么。溶液1的性能为O(nm),其中
n
是组合数,
m
是每个组合的值数。不可能小于此值,因为您必须为结果添加那么多值。您的解决方案的时间复杂度为O(n^2)。这比我的解决方案有改进吗?