【问题标题】:Build all possible sorted combinations of a List<string>构建 List<string> 的所有可能的排序组合
【发布时间】:2014-10-25 11:59:17
【问题描述】:

我有一个 .Net 列表,我想知道最(或“合理”接近)有效的方法是以下列方式组合它们:

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

  1. 一个
  2. B
  3. C
  4. A B
  5. A C
  6. BC
  7. A B C

基本上,内部元素的顺序必须保持不变(A > B > C),因此只有例如4.) 上面的 'A B' 是可能的/应该返回,但反过来 ('B A') 则不行。

我一直在摆弄这个问题,但目前我的代码远非优雅,但也许有人已经做过类似的事情并且知道如何正确/有效地做到这一点。

【问题讨论】:

    标签: .net algorithm sorting combinations


    【解决方案1】:

    我能想到的生成这样的集合的方法有以下三种:

    元素的位表示在您的示例中,您可以从 1 迭代到 1 &lt;&lt; length(排他性)并从设置的位构建列表:

    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 &lt;&lt; length空列表开头。将第一个元素放在后半部分的所有列表中。将第二个元素放在第二和第四季度的所有列表中。将每个列表中的第三个元素放在第 2、第 4、第 6 和第 8 个八分圆中。等等。这实际上只是递归方法的迭代变体,还将创建空列表。 (它也与位模式解决方案相关。)

    【讨论】:

      【解决方案2】:

      目前我认为返回的顺序无关紧要。我将按以下顺序返回元素:

      1. A
      2. B
      3. A B
      4. C
      5. A C
      6. B C
      7 A B C
      

      如果这对您不起作用,请回信,我会尝试找出可行的算法。

      这个顺序对您来说可能有点奇怪,但如果您迭代所有可能的元素组合,这是您将收到的直截了当的顺序。

      对于每种元素组合,我都会在您选择元素的地方分配带有 1 的二进制掩码。因此,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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-03-10
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        • 2021-03-19
        • 2016-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多