我需要通过组合中的数字来减小集合的大小。我需要所有可能的组合。 以下两个例子可以说明我的情况。
1)Set1有4个条目,Set2有2个。所以我们需要在每种情况下组合两个数字。
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)Set1有4个条目,Set2有3个。所以我们只需要合并两个数字。
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
我感谢任何帮助。我想不出任何可以更好地解释我关注的话。但我很乐意回答任何问题。在你的帮助下,我可以证实我的问题。 虽然应用程序是用C#编写的,但我不一定需要源代码。我的问题不是概念而是实施。
提前感谢!
答案 0 :(得分:0)
您问题的主要困难是:
这是我的想法: 我想你的第一套不会超过32个元素。否则,结果会非常巨大。
然后,对于给定的集合MySet = { a, b, c, d, e }
,可以使用0
和2^5 - 1
之间的值来描述此集合的每个子集。
怎么样?
使用这些位!好的,例如,数字5
(00101
二进制)表示,a
和c
包含在子集中。
所以要拥有一组给定N
个元素的子集的整个集合。
只需从0
迭代到2^N-1
排除。
只需获取第一组的补码并迭代其子集。
获取以前部分的补充!
有可能不必使用此技术查找前一个子集的补码,但它需要一些非标准的按位运算。
答案 1 :(得分:0)
好的,所以这里的一般想法是
{0, 0, 0, 0}
开始 - Set1
的每个元素都为零。0
代表Set2
中的第一项。因此,第一个数组是“Set1
中的所有内容属于Set2
中的第一项”。{0, 0, 0, 0}
增加到{0, 0, 0, 1}
。1
代表Set2
中的第二项。因此,此数组是“Set1
中的所有内容属于Set2
中的第一项,除了最后一项,属于Set2
中的第二项。”{0, 0, 0, 1}
增加到{0, 0, 1, 0}
(如果{0, 0, 0, 2}
中的项目数超过2个,则为Set2
。){1, 1, 1, 1}
(或{2, 2, 2, 2}
等)并且无法再继续。然后,您可以添加逻辑说“如果某个分区有任何空部分,请不要理会它。”
我按如下方式实现了这个:
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
。