在一组数字池号码相匹配的另一组的大小相匹配、大小、号码、另一组

2023-09-11 05:04:29 作者:玩膩丶ceiling

我需要通过在其组合编号,以减少一组的大小。我需要的所有可能的组合。 这里有两个例子可以说明我的情况。

I need to reduce the size of a set by combining the numbers in it. I need all possible combinations. Here are two examples that might illustrate my situation.

1)设置1有4项,设置2有2所以我们需要两个数字组合在每种情况下。

1) Set1 has 4 entries and Set2 has 2. So we need to combine two numbers in each case.

Set1 = {70, 100, 50, 200}; Set2 = {"part1", "part2"}
All combinations I want to retrive should look like following:
"part1"        |"part2"
  70 + 100       |  50 + 200
  70 + 50        | 100 + 200
  70 + 200       |  50 + 100
 100 + 50       |  70 + 200
 100 + 200      |  50 +  70
  50 + 200       | 100 +  70
 50             |  70 + 100 + 200
 70             |  50 + 100 + 200
 100            |  50 +  70 + 200
 200            |  50 +  70 + 100  
 70 + 100 + 200 |  50
 50 + 100 + 200 |  70
 50 +  70 + 200 |  100
 50 +  70 + 100 |  200 

2)设置1有4项,设置2拥有3。因此,我们需要结合只是一次两个数字。

2) Set1 has 4 entries and Set2 has 3. So we need to combine two numbers just once.

Set1 = {70, 100, 50, 200}; Set2 = {"part1", "part2", "part3"}
All combinations I want to retrive should look like following:
"part1"   |"part2"     |"part3"
   70        | 100        |  50 + 200
   70        |  50        | 100 + 200
   70        | 200        |  50 + 100
   50        |  70        | 100 + 200 
   50        | 100        |  70 + 200
   50        | 200        |  70 + 100
 100       |  70        |  50 + 200
 100       | 200        |  50 +  70
 100       |  50        | 200 +  70
 200       |  70        |  50 + 100
 200       | 100        |  50 +  70
 200       |  50        |  70 + 100
   70        |  50 + 200  |  100
   70        | 100 + 200  |   50
   70        |  50 + 100  |  200
   50        | 100 + 200  |   70
   50        | 200 + 70   |  100
   50        |  70 + 100  |  200
 100       |  50 + 200  |   70
 100       |  50 +  70  |  200
 100       | 200 +  70  |   50
 200       |  50 + 100  |   70
 200       |  50 +  70  |  100
 200       |  70 + 100  |   50 
   50 + 200  | 100        |  70
 100 + 200 |  50        |  70
   50 + 100  | 200        |  70
 100 + 200 |  70        |  50
   70 + 200  | 100        |  50
   70 + 100  | 200        |  50
   50 + 200  |  70         | 100
   50 +  70  | 200         | 100
 200 +  70 |  50         | 100
   50 + 100  |  70         | 200
   50 +  70  | 100         | 200
   70 + 100  |  50         | 200

我AP preciate任何帮助。我想不出任何话来解释我所关注的更好。不过,我会很乐意回答任何问题。随着你帮我也许能证实我的问题。 虽然应用程序是用C#我不一定需要源$ C ​​$ C。我的问题是,而不是执行理念。

I appreciate any help. I cannot think of any words to explain my concern better. But I will be very happy to answer any question. With you help I might be able to substantiate my question. Although the application is written in C# i don't necessarily need source code. My problem is rather the concept than the implementation.

在此先感谢!

推荐答案

好了,所以这里的总体思路是

OK, so the general idea here is

这是一个零设置1 中的每个元素 - 与 {0,0,0,0} 开始关闭 0 重presents的第一项设定2 。因此,这第一个数组是一切都在设置1 属于第一项设定2 返回与此对应的分区。 增量 {0,0,0,0} {0,0,0,1} 1 重presents第二项设定2 。因此,这个数组是一切都在设置1 属于第一项设定2 ,除了最后一个,属于在设定2 第二项 返回与此对应的分区。 增量 {0,0,0,1} {0,0,1,0} (或 {0,0,0,2} 如果你有超过2项设定2 )。 重复,直到你打 {1,1,1,1} (或 {2,2,2,2} 等),不能再增加了。 Start off with {0, 0, 0, 0} - that's a zero for each element of Set1. 0 represents the first item in Set2. Thus this first array is "everything in Set1 belongs to the first item in Set2". Return a partition corresponding to this. Increment {0, 0, 0, 0} to {0, 0, 0, 1}. 1 represents the second item in Set2. Thus this array is "everything in Set1 belongs to the first item in Set2, except the last, which belongs to the second item in Set2". Return a partition corresponding to this. Increment {0, 0, 0, 1} to {0, 0, 1, 0} (or {0, 0, 0, 2} if you have more than 2 items in Set2). Repeat until you hit {1, 1, 1, 1} (or {2, 2, 2, 2} etc.) and can't go any further.

您可以再添加的逻辑说:如果一个分区有任何的空的部分,不要理会它。

You can then add logic saying "if a partition has any empty parts, don't bother with it".

我实现了这个如下:

static IEnumerable<ILookup<T, U>> Pool<T, U>(T[] t, U[] u)
{
    // Start off with all zeroes.
    int[] indices = new int[u.Length];

    while (true)
    {
        // Build a Lookup from the array.
        var lookup = (Lookup<T,U>)indices
            .Select((ti, ui) => new { U = u[ui], T = t[ti] })
            .ToLookup(p => p.T, p => p.U);
        // Only return it if every part is non-empty.
        if (lookup.Count == t.Length)
            yield return lookup;

        // Increment to the next value.
        int toIncrement = u.Length - 1;
        while (++indices[toIncrement] == t.Length)
        {
            indices[toIncrement] = 0;

            // Stop when we can't increment further.
            if (toIncrement-- == 0)
                yield break;
        }
    }
}

您可以为

foreach (var q in Pool(
    new[] { "part1", "part2" },
    new[] { 70, 100, 50, 200 }))
{
    foreach (int i in q["part1"])
        Console.Write(i + " ");
    Console.Write("| ");
    foreach (var ii in q["part2"])
        Console.Write(ii + " ");
    Console.WriteLine();
}

请注意,因为我很懒,我做了我的参数数组,但是你可以让他们列出,或使它们可枚举,并呼吁的ToArray 在他们身上。

Note I've made my parameters arrays because I'm lazy, but you could make them lists, or make them enumerables and call ToArray on them.