代码之家  ›  专栏  ›  技术社区  ›  Thorin Oakenshield

如何在C#中获得连续字符?

  •  6
  • Thorin Oakenshield  · 技术社区  · 14 年前

    我有一个

    List<String> MyList=new List<string>();
    

    我要把名单填上 MyList n 价值观。

    如果n的值是2,那么 迈利斯特 将包含

    "A","B"
    

    如果10那么

    "A","B","C"....."J"
    

    如果30那么

    "A"....."Z","AA","AB",AC","AD"
    

    如果1000那么

    "A",....."Z","AA","AB"......"AZ","BA","BB"......."BZ"........"YZ","AAA",AAB".....
    and so on
    

    我不知道怎么做。

    LINQ LAMBDA Expression

    6 回复  |  直到 14 年前
        1
  •  6
  •   larsw    11 年前

    编辑2 :

    . 我测试过了,效果很好。您可以生成无限个字符串。

    public IEnumerable<string> GenerateStrings()
    {
        foreach(string character in Alphabet())
        {
          yield return character;
        }
    
        foreach (string prefix in GenerateStrings())
        {
          foreach(string suffix in Alphabet())
          {
            yield return prefix + suffix;
          }
        }
    }
    
    public IEnumerable<string> Alphabet()
    {
        for(int i = 0; i < 26; i++)
        {
          yield return ((char)('A' + i)).ToString();
        }
    }
    

    我以前写过的东西:

    它很短很简单:

    string GetString(int index)
    {
      if (index < 26)
      {
        return ((char)('A' + index)).ToString();
      }
      return GetString(index / 26 - 1) + GetString(index % 26);
    }
    

    用法(也可用于其他方法:

    List<string> strings = Enumerable.Range(0, 1000)
      .Select(x => GetString(x))
      .ToList();
    

    这是有效的代码,只是为它编写了一个测试。


    例如,GetString的“full linq way”应用程序:

    public void IEnumerale<string> GenerateStrings()
    {
      int index = 0;
      // generate "infinit" number of values ...
      while (true)
      {
         // ignoring index == int.MaxValue
         yield return GetString(index++);
      }
    }
    
    List<string> strings = GenerateStrings().Take(1000).ToList();
    
        2
  •  3
  •   Community CDub    8 年前

    这与 this question (但还不足以将其标记为副本,而且无论如何,这是一个很难搜索的问题)。

    使用任何工作 IEnumerable<string>

    List<string> list = GenerateSequence().Take(count).ToList();
    
        3
  •  3
  •   Community CDub    8 年前

    我做的 something similar 在SQL中。

    public static string GetCode(int id) {
      string code, chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      if (id <= chars.Length) {
        code = chars.Substring(id - 1, 1);
      } else {
        id--;
        int value = chars.Length, adder = 0;
        while (id >= value * (chars.Length + 1) + adder) {
          adder += value;
          value *= chars.Length;
        }
        code = chars.Substring((id - adder) / value - 1, 1);
        id = ((id - adder) % value);
        while (value > 1) {
          value /= chars.Length;
          code += chars.Substring(id / value, 1);
          id = id % value;
        }
      }
      return code;
    }
    

    然后你只需要从1和1以上得到数字,然后转换成代码:

    var codes = Enumerable.Range(1, 1000).Select(n => GetCode(n));
    

    函数的限制当前为“ZZZZZZ”或321272406。(在那之后你得到一个零的除法。)

    请注意,此函数使用所有组合并返回“A”..“Z”、“AA”..“ZZ”、“AAA”..“ZZZ”,而不是从“AB”和“ABC”开始。

        4
  •  3
  •   Cheng Chen    14 年前

    这段代码运行良好,但我不确定它是否足够“LINQ”。

    char[] validChars = Enumerable.Range(0, 26).Select(i => (char)('A' + i)).ToArray();
    List<string> result = new List<string>();
    List<string> generator = validChars.Select(ch => ch.ToString()).ToList();
    
    int n = 1000;
    
    while (result.Count < n)
    {
        result.AddRange(generator);
        generator = generator.Take((n - result.Count) / validChars.Length + 1)
                             .SelectMany(s => validChars.Select(ch => s + ch))
                             .ToList();
    }
    
    var output = result.Take(n);
    
        5
  •  1
  •   priyanka.sarkar    14 年前

    试试下面的。。我在用 交叉连接 工会 采用可拓方法

    char[] charArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
    
    List<String> MyList = new List<string>();
    int n = 1000;
    
                          (from value1 in charArray
                           select new
                           {
                               newString = value1.ToString()
                           })
                       .Union
                       (
                           (from value1 in charArray
                            from value2 in charArray
    
                            select new
                            {
                                newString = string.Concat(value1, value2)
                            })
                        )
                        .Union
                        (
                            (from value1 in charArray
                             from value2 in charArray
                             from value3 in charArray
    
                             select new
                             {
                                 newString = string.Concat(value1, value2, value3)
                             })
                         )
                         .Take(n)
                         .ToList()                         
                         .ForEach(i => MyList.Add(i.newString));
    

    希望这将给您一些使用Linq、Lambda和扩展方法组合的想法。

        6
  •  0
  •   abatishchev Karl Johan    14 年前

    @丹宁臣就这样。你的代码稍有改动。。

    char[] validChars = Enumerable.Range(0, 26).Select(i => (char)('A' + i)).ToArray();
    
    int n = 30;
    int pointer = 0;
    int pointerSec = 0;
    int Deg = 0;
    string prefix = string.Empty;
    string prefixMore = string.Empty;
    List<string> result = new List<string>();
    
    while (n > 0)
    {
        result.AddRange(validChars.Skip(pointer).Select(ch => prefix + ch).Take(n));
        if (pointer == 26)
        { 
            pointer = -1;
            Deg += 1;
            prefixMore = "" + validChars[pointerSec];
            pointerSec++;
            n++;
        }
        else
        {
            if (Deg == 0)
            {
                prefix = "" + validChars[pointer];
            }
            else
            {
                prefix = prefixMore + validChars[pointer];
            }
        }
        n--;
        pointer++;
    }