我有一个.Net列表,我想知道最有效的方法是什么(或#34; 合理"关闭)以下列方式组合这些方法:
鉴于列表中有3个元素(' A',' B'和' C')我基本上需要从方法返回以下内容:
基本上,内部元素的顺序必须保持不变(A> B> C)&因此只有例如4.)' A B'以上是可能的/应该返回,但反过来(' B A')没有。
我现在已经摆弄了一段时间,但我目前还远没有优雅的代码,但也许有人已经做了类似的事情并知道如何正确/有效地做到这一点。
答案 0 :(得分:1)
有三种方法可以生成我能想到的这样的集合:
元素的位表示在示例中,您可以从1
迭代到1 << length
(exclusivley)并从设置位构建列表:
1 001 {A}
2 010 {B}
3 011 {A, B}
4 100 {C}
5 101 {A, C}
6 110 {B, C}
7 111 {A, B, C}
当你以相反的方式进行排序时,列表列表本身是有序的,即顶部位代表A而不是最低位。
二进制递归递归列表的元素,在每个步骤中,您沿着两条路径前进:包含当前元素或丢弃它。当你递归时,你将不得不建立一个列表;处理完原始列表的所有元素后,将其添加到结果中。
这可能比每次从位模式构建列表更有效。它还会生成空列表,您应该特别对待它。
填写从1 << length
空列表开始。将第一个元素放在后半部分的所有列表中。将第二个元素放在第二个和第四个季度的所有列表中。将第三个元素放在第2个,第4个,第6个和第8个八分圆的每个列表中。等等。这实际上只是递归方法的迭代变体,并且还将创建空列表。 (它还与位模式解决方案相关。)
答案 1 :(得分:0)
目前我认为退货顺序无关紧要。我将按以下顺序返回元素:
1. A
2. B
3. A B
4. C
5. A C
6. B C
7 A B C
如果这对您不起作用,请回信,我将尝试找出工作算法。
这个顺序对你来说似乎有些奇怪,但如果你迭代所有可能的元素组合,这就是你将获得的straigt前向顺序。
对于每个元素组合,我在您选择元素的地方分配二元模板。因此,A是第一位,B是第二位,C是第三位(我给出了三个元素的例子,但这显然可以扩展到更多元素)。
A B -> 011 = 3
C -> 100 = 4
B C -> 110 = 6
我会在C ++中给oyu伪代码,因为我不是.Net的主人,但我相信你能将它转换成你的语言。
void printCombination(List<Element> elements, int mask) {
int n = elements.size(); // number of elements
for (int i = 0; i < n; i++) {
bool elementPrinted = false;
if (mask & (1 << i)) { //if the ith bit is set
if (elementPrinted) cout << " "; // adding separator
cout << elements.get(i);
elementPrinted = true;
}
cout << "\n";
}
}
void getAllCombinations(List<Element> elements) {
int n = elements.size(); // number of elements
for (int mask = 1; mask < (1 << n); mask++) { // iterate all possible submasks
printCombination(elements, mask);
}
}