代码之家  ›  专栏  ›  技术社区  ›  Andras Zoltan

计算一组n个集合的串联集合

  •  5
  • Andras Zoltan  · 技术社区  · 15 年前

    已绑定 但我会尽力解释的。这不完全是一个交叉积,结果的顺序是绝对关键的。

    IEnumerable<IEnumerable<string>> sets = 
          new[] { 
                  /* a */ new[] { "a", "b", "c" },
                  /* b */ new[] { "1", "2", "3" },
                  /* c */ new[] { "x", "y", "z" }
                };
    

    其中,每个内部可枚举数表示一条指令,以生成一组串联,如下所示(此处的顺序很重要):

    set a* = new string[] { "abc", "ab", "a" };
    set b* = new string[] { "123", "12", "1" };
    set c* = new string[] { "xyz", "xy", "x" };
    

    set final = new string { a*[0] + b*[0] + c*[0], /* abc123xyz */
                             a*[0] + b*[0] + c*[1], /* abc123xy  */
                             a*[0] + b*[0] + c*[2], /* abc123x   */
                             a*[0] + b*[0],         /* abc123    */
                             a*[0] + b*[1] + c*[0], /* abc12xyz  */
                             a*[0] + b*[1] + c*[1], /* abc12xy   */
                             a*[0] + b*[1] + c*[2], /* abc12x    */
                             a*[0] + b*[1],         /* abc12     */
                             a*[0] + b*[2] + c*[0], /* abc1xyz   */
                             a*[0] + b*[2] + c*[1], /* abc1xy    */
                             a*[0] + b*[2] + c*[2], /* abc1x     */
                             a*[0] + b*[2],         /* abc1      */
                             a*[0],                 /* abc       */
                             a*[1] + b*[0] + c*[0], /* ab123xyz  */
    
                             /* and so on for a*[1] */
                             /* ... */
    
                             a*[2] + b*[0] + c*[0], /* a123xyz   */
    
                             /* and so on for a*[2] */
                             /* ... */
    
                             /* now lop off a[*] and start with b + c */
    
                             b*[0] + c*[0],         /* 123xyz    */
    
                             /* rest of the combinations of b + c
                                with b on its own as well */
    
                             /* then finally */
                             c[0],
                             c[1],
                             c[2]};
    

    很明显,会有很多组合!

    我可以看到与数字基的相似之处(因为顺序也很重要),我确信这里也隐藏着排列/组合。

    问题是-如何编写这样的算法来处理任意数量的字符串集?Linq,非Linq;我不大惊小怪。

    我为什么要这么做?

    View ,我们可以 View-en-GB , View-en View-GB ,和 查看 ,按照优先顺序(当然要认识到语言/文化代码可能是相同的,所以有些组合 一模一样-a Distinct()

    但我也有其他观点,在文化被考虑之前,它们本身就有其他可能的组合(太长了,无法深入讨论-但事实是,这个算法将使一大堆 真正地

    我要生成一个包含所有可接受视图名称的搜索列表,遍历整个批,直到 最具体的

    我已经有了这个工作的一个非常基本的版本,只有一个字符串可枚举。但这是一壶完全不同的海鲜!

    非常感谢您的帮助。

    3 回复  |  直到 15 年前
        1
  •  3
  •   Botz3000 Amir Sheng    15 年前

    这是我的尝试:

    void Main()
    {
        IEnumerable<IEnumerable<string>> sets = 
              new[] { 
                      /* a */ new[] { "a", "b", "c" },
                      /* b */ new[] { "1", "2", "3" },
                      /* c */ new[] { "x", "y", "z" }
                    };
    
        var setCombinations = from set in sets
                              select (from itemLength in Enumerable.Range(1, set.Count()).Reverse()
                                      select string.Concat(set.Take(itemLength).ToArray()));
    
        IEnumerable<string> result = new[] { string.Empty };
    
        foreach (var list in setCombinations) {
            result = GetCombinations(result, list);
        }
        // do something with the result
    }
    
    IEnumerable<string> GetCombinations(IEnumerable<string> root, IEnumerable<string> append) {
        return from baseString in root
               from combination in ((from str in append select baseString + str).Concat(new [] { baseString }))
               select combination;
    }
    
        2
  •  2
  •   Lasse V. Karlsen    15 年前

    这将产生您想要的:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    
    namespace SO3014119
    {
        class Program
        {
            private static IEnumerable<string> GetStringCombinations(
                string prefix, 
                IEnumerable<string>[] collections, int startWithIndex)
            {
                foreach (var element in collections[startWithIndex])
                {
                    if (startWithIndex < collections.Length - 1)
                    {
                        foreach (var restCombination in
                            GetStringCombinations(prefix + element, collections,
                                startWithIndex + 1))
                        {
                            yield return restCombination;
                        }
                    }
    
                    yield return prefix + element;
                }
            }
    
            public static IEnumerable<string> GetStringCombinations(
                params IEnumerable<string>[] collections)
            {
                while (collections.Length > 0)
                {
                    foreach (var comb in GetStringCombinations("", collections, 0))
                        yield return comb;
    
                    // "lop off" head and iterate
                    collections = collections.Skip(1).ToArray();
                }
            }
    
            static void Main(string[] args)
            {
                var a = new string[] { "a1", "a2", "a3" };
                var b = new string[] { "b1", "b2", "b3" };
                var c = new string[] { "c1", "c2", "c3" };
    
                foreach (string combination in GetStringCombinations(a, b, c))
                {
                    Console.Out.WriteLine(combination);
                }
            }
        }
    }
    

    这将产生(注意,我更改了输入集合中的条目,以便更容易地看到它们是如何组合的):

    a1b1c1
    a1b1c2
    a1b1c3
    a1b1
    a1b2c1
    a1b2c2
    a1b2c3
    a1b2
    a1b3c1
    a1b3c2
    a1b3c3
    a1b3
    a1
    a2b1c1
    a2b1c2
    a2b1c3
    a2b1
    a2b2c1
    a2b2c2
    a2b2c3
    a2b2
    a2b3c1
    a2b3c2
    a2b3c3
    a2b3
    a2
    a3b1c1
    a3b1c2
    a3b1c3
    a3b1
    a3b2c1
    a3b2c2
    a3b2c3
    a3b2
    a3b3c1
    a3b3c2
    a3b3c3
    a3b3
    a3
    b1c1
    b1c2
    b1c3
    b1
    b2c1
    b2c2
    b2c3
    b2
    b3c1
    b3c2
    b3c3
    b3
    c1
    c2
    c3
    
        3
  •  1
  •   apoorv020    15 年前

    解决方案似乎很简单(算法上)

    在每个数组a*、b*、c的末尾添加一个extry空字符串*

    string[] a* = { "abc","ab","a","" };
    string[] b* = { "123","12","1","" };
    string[] c* = { "xyz","xy","x","" };
    
    List<string> final = new List<string>();
    

    foreach(string aMember in a*)
    foreach(string bMember in b*)
    foreach(string cMember in c*)
    final.add(aMember+bMember+cMember);
    

    a*、b*和c*末尾的多余空字符串将按所需顺序生成特殊字符串,如a[0](=a[0]+b[3]+c[3])。

    推荐文章