构建List <string> </string>的所有可能的排序组合

时间:2014-10-25 11:59:17

标签: .net algorithm sorting combinations

我有一个.Net列表,我想知道最有效的方法是什么(或#34; 合理&#34;关闭)以下列方式组合这些方法:

鉴于列表中有3个元素(&#39; A&#39;,&#39; B&#39;和&#39; C&#39;)我基本上需要从方法返回以下内容:

  1. A
  2. C
  3. A B
  4. A C
  5. B C
  6. A B C
  7. 基本上,内部元素的顺序必须保持不变(A> B> C)&amp;因此只有例如4.)&#39; A B&#39;以上是可能的/应该返回,但反过来(&#39; B A&#39;)没有。

    我现在已经摆弄了一段时间,但我目前还远没有优雅的代码,但也许有人已经做了类似的事情并知道如何正确/有效地做到这一点。

2 个答案:

答案 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);
    }
}