【问题标题】:Combinations of 4 points from 2 arrays of points来自 2 个点数组的 4 个点的组合
【发布时间】:2012-11-12 21:03:55
【问题描述】:

我有两个二维点数组:

array1 = int[x][2]
array2 = int[y][2]

我想从这两个数组中生成 4 个点的组合。结果应该在一个列表中:

List<int[4][2]>

但我需要指定每个组合从 array1 中获取的点数(并从 array2 中获取剩余的点)。点的顺序无关紧要。而且不应该有重复。

例如:

array1={ {0,0} , {0,1} , {1,0} }
array2= { {1,1} , {2,1} , {2,2} , ... , {9,9} }

(从array1中取1点,从array2中取3点)

res= { {0,0} , {1,1} , {2,1} , {2,2} }
     { {0,0} , {1,1} , {2,1} , {3,2} }
     ...
     { {0,0} , {1,1} , {2,1} , {9,9} }
     ...
     { {0,1} , {1,1} , {2,1} , {2,2} }
     ...

从不:

res = { {0,0} , {1,1} , {1,1} , {1,1} }
      ...

两者都不是:

res= { {0,0} , {1,1} , {2,1} , {2,2} }
     { {0,0} , {1,1} , {2,2} , {2,1} }
     ...

(从array1中取2点,从array2中取2点)

...

(从array1中取3点,从array2中取1点)

...

我希望有人可以帮助我,因为我花了很多时间阅读/测试了很多答案,但找不到解决方案。

PS/Edit:如果你能提供 C# 代码,那就太好了。

【问题讨论】:

    标签: c# algorithm combinations jagged-arrays


    【解决方案1】:

    通过 Nuget 下载Combinatorics Library for .Net

    我试了一下:

        Dim a1 = {New Integer() {0, 0}, New Integer() {1, 1}, New Integer() {2, 2}}
        Dim a2 = {New Integer() {3, 3}, New Integer() {4, 4}, New Integer() {5, 5}, New Integer() {6, 6}}
    
        Dim combA1 = New Combinations(Of Integer())(a1, 1)
        Dim combA2 = New Combinations(Of Integer())(a2, 3)
    
        Dim l As New List(Of Integer()())
        For Each i In combA1
            For Each j In combA2
                l.Add(i.Union(j).ToArray)
            Next
        Next
    

    不要忘记导入 Combinatorics.Collections 命名空间。 结果对我来说看起来不错,但您可能需要花更多时间来检查它。 for 循环看起来可以用一个简单的 LINQ 语句代替,但它确实有效。

    【讨论】:

    • 感谢您的回答,但我正在寻找一个我可以自己实现的功能,而不是打包的组合库。如果我不能得到它,我会尝试这种方法(并且可能会查看源代码以尝试提取此功能)。
    【解决方案2】:

    这个问题已经被你的规定简化了,你只能按照它们在原始数组中的存储顺序来检索点。

    编辑:这个问题已经被您的规定简化了,即结果应该包含组合,而不是排列。因此,为了简化事情,我们可以按照它们在原始数组中的存储顺序检索点,这样可以避免对它们进行置换。

    您提出翻译任何其他语言,所以我将使用 JavaScript。请注意,JavaScript 数组包含它们的长度,因此您需要单独传递长度(或者传递数组的末尾)。

    function combinations(array1, count1, array2, count2)
    {
        var result = [];
        combine(array1, 0, count1, array2, 0, count2, [], result);
        return result;
    }
    
    function combine(array1, offset1, count1, array2, offset2, count2, chosen, result)
    {
        var i;
        var temp;
        if (count1) {
            count1--;
            for (i = offset1; i < array1.length - count1; i++) {
                temp = chosen.concat([array1[i]]); // this copies the array and appends the item
                combine(array1, i + 1, count1, array2, offset2, count2, temp, result);
            }
        } else if (count2) {
            count2--;
            for (i = offset2; i < array2.length - count2; i++) {
                temp = chosen.concat([array2[i]]);
                combine(null, 0, 0, array2, i, count2, temp, result);
            }
        } else {
            result.push(chosen); // don't need to copy here, just accumulate results
        }
    }
    

    【讨论】:

    • "您只能按照它们在原始数组中的存储顺序检索点。"我没有明确说过。你的意思是顺序无关紧要吗?而且我高估了我翻译代码的能力。pastebin.com/3mZVrjeu 这是我的尝试,但还远远不够。你能帮我翻译一下吗?
    • @joaoroque 一种方法是使用 Skip 从数组中删除第一个 i + 1 元素。另一种方法是传递偏移量。我将更新代码以使用该方法。
    猜你喜欢
    • 2021-09-29
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    相关资源
    最近更新 更多