【问题标题】:find combinatios of list items查找列表项的组合
【发布时间】:2012-05-17 02:59:48
【问题描述】:

我有 n 个带有项目的 inputLists。 现在我想计算包含原始 inputLists 中所有项目组合的 resultLists(长度为 n)(取每个 inputList 中的一项)。

我想我应该在这里举一个例子(n=3):

inputList1: [item1, item2, item3]
inputList2: [item4]
inputList3: [item5, item6]

resultList1: [item1, item4, item5]
resultList2: [item1, item4, item6]
resultList3: [item2, item4, item5]
resultList4: [item2, item4, item6]
resultList5: [item3, item4, item5]
resultList6: [item3, item4, item6]

我感觉有点愚蠢,但我不知道如何实现(C++)一个函数,为任何 n 和任何 inputList 长度创建这些结果。我想我应该使用某种递归,但我不知道如何。
有什么想法吗?

【问题讨论】:

标签: c++ cartesian-product


【解决方案1】:

一个总体思路,用伪代码表示:

vector<item> List1, List2, List3;
// fill the lists

vector<item> v;
vector<vector<item>> results;

for each item i in List1
{
    v.push_back(i)
    for each item j in List2
    {
        v.push_back(j);
        for each item k in List3
        {
            v.push_back(k);
            results.push_back(v);
            v.pop_back();
        }
        v.pop_back();
    }
    v.pop_back();
}

要对可变数量的列表执行此操作,我会采用递归方法。然后每个 for 循环将被一个递归函数调用替换。此函数需要接受您的inputLists 列表、结果列表和将中间结果(上例中为v)存储为参数的容器。

希望对您有所帮助。

【讨论】:

  • 这比我想象的要容易。谢谢!
【解决方案2】:

迭代器是你的朋友。两个伪代码版本,无需担心错误检查或零大小列表等极端情况:

struct cartesian_product_iterator {
    int indexes[n] initialized to zeroes
    operator++() {
        a = 0
        indexes[a]++;
        while a < n and indexes[a] >= list[a].size()
            indexes[a] = 0
            a++;
    }
    operator *() {
        list<?> ret;
        for a in 0..n-1:
            ret.push_back(list[a][indexes[a]]);
        return ret;
    }
    past_the_end_iterator() { indexes[n-1] = list[n-1].size(); }
}

您可能会注意到indexes 数组只是将整数分解为多个基数。这导致了第二种解决方案:

struct cartesian_product_iterator_2 {
    unsigned_or_arbitrarly_big_int a_large_number = 0;
    operator ++()  { a_large_number++; }
    operator *() {
        list<?> ret;
        unsigned_or_arbitrarly_big_int to_decompose = a_large_number;
        for a in 0..n-1:
            index = to_decompose % list[a].size();
            to_decompose /= list[a].size();
            ret.push_back(list[a][index]);
        }
        return ret;
    }
    past_the_end_iterator() {
       a_large_number = 1;
       for each l in list:
           a_large_number *= l.size();
    }
}

至于哪个最好/更快,我真的不知道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    相关资源
    最近更新 更多