【问题标题】:C# looping through a list to find character countsC#循环遍历列表以查找字符数
【发布时间】:2021-08-06 05:57:51
【问题描述】:

我正在尝试遍历字符串以查找字符、ASCII 值以及字符出现的次数。到目前为止,我已经使用 foreach 语句找到了每个唯一字符和 ASCII 值,并查找该值是否已经在列表中,然后不要添加它,否则添加它。但是我在计数部分苦苦挣扎。我在想逻辑是“如果我已经在列表中,不要再数我,但是,增加我的频率” 我尝试了一些不同的方法,例如尝试找到它找到的字符的索引并添加到​​该特定索引,但我迷路了。

    string String = "hello my name is lauren";
        char[] String1 = String.ToCharArray();
       // int [] frequency = new int[String1.Length]; //array of frequency counter
        int length = 0;         
        
        

        List<char> letters = new List<char>();
        List<int> ascii = new List<int>();
        List<int> frequency = new List<int>();


        foreach (int ASCII in String1)
        {
            bool exists = ascii.Contains(ASCII);
            if (exists)
            {
                //add to frequency at same index
                //ascii.Insert(1, ascii);
                //get { ASCII[index]; }
            }
            else
            {
                ascii.Add(ASCII);
                //add to frequency at new index
                
            }
        }


        foreach (char letter in String1)
        {
            bool exists = letters.Contains(letter);
           if (exists)
            {
              //add to frequency at same index

            }
            else
            {
                letters.Add(letter);
                //add to frequency at new index
            }
        }



        
        length = letters.Count;
        for (int j = 0; j<length; ++j)
        {
            Console.WriteLine($"{letters[j].ToString(),3}  {"(" + ascii[j] + ")"}\t");
        }

        Console.ReadLine();
    }
}

}

【问题讨论】:

  • LINQ 的GroupBy 是一个选项吗?
  • 此时任何东西都是一个选项。我的输出与每个字符、ASCII 值和频率非常接近。但是每个频率都为 0,因为该数组中没有添加任何内容
  • 如果您不介意性能下降,您可以使用string.Replace(charYourLookingFor,Char.MinValue) 并比较它们的长度以获取该字符在字符串中出现的次数。
  • @DekuDesu 如果字符是 Char.MinValue 怎么办?
  • 如果需要找到字符'\0',则可以使用string.Replace($"{charYourLookingFor}","")

标签: c# arrays loops foreach


【解决方案1】:

我不确定我是否理解您的问题,但您正在寻找的可能是 Dictionary 而不是 List。以下是我认为您试图解决的问题的解决方案示例。

人物出现次数统计

Dictionary<int, int> frequency = new Dictionary<int, int>();                
            foreach (int j in String)
            {
                if (frequency.ContainsKey(j))
                {
                    frequency[j] += 1;
                }
                else
                {
                    frequency.Add(j, 1);
                }
            }

将字符链接到其 ASCII 的方法

Dictionary<char, int> ASCIIofCharacters = new Dictionary<char, int>();

        foreach (char i in String)
        {
            if (ASCIIofCharacters.ContainsKey(i))
            {

            }
            else
            {
                ASCIIofCharacters.Add(i, (int)i);
            }
        }

【讨论】:

  • TryGetValue 会比ContainsKey 更好。
【解决方案2】:

一个简单的 LINQ 方法就是这样做:

string String = "hello my name is lauren";

var results =
    String
        .GroupBy(x => x)
        .Select(x => new { character = x.Key, ascii = (int)x.Key, frequency = x.Count() })
        .ToArray();

这给了我:

【讨论】:

    【解决方案3】:

    如果我理解您的问题,您想将提供的字符串中的每个 char 映射到它在字符串中出现的次数,对吗?

    如果是这种情况,有很多方法可以做到这一点,而且您还需要选择要将结果存储在哪种数据结构中。

    假设您想使用 linq 并将结果存储在 Dictionary&lt;char, int&gt;, 中,您可以执行以下操作:

    static IDictionary<char, int> getAsciiAndFrequencies(string str) {
      return (
        from c in str
        group c by Convert.ToChar(c)
      ).ToDictionary(c => c.Key, c => c.Count());
    }
    

    如果这样使用:

    var f = getAsciiAndFrequencies("hello my name is lauren");
    // result: { h: 1, e: 3, l: 3, o: 1, ... }
    

    【讨论】:

      【解决方案4】:

      您正在创建一个直方图。但是你不应该使用List.Contains,因为它会随着列表的增长而失效。您必须一个接一个地浏览列表。最好使用基于散列的Dictionary,您可以直接进入该项目。代码可能是这样的

      string str = "hello my name is lauren";
      
      var dict = new Dictionary<char, int>();
      foreach (char c in str)
      {
          dict.TryGetValue(c, out int count);
          dict[c] = ++count;
      }
      
      foreach (var pair in dict.OrderBy(r => r.Key))
      {
          Console.WriteLine(pair.Value + "x " + pair.Key + " (" + (int)pair.Key + ")");
      }
      

      给了

      4x   (32)
      2x a (97)
      3x e (101)
      1x h (104)
      1x i (105)
      3x l (108)
      2x m (109)
      2x n (110)
      1x o (111)
      1x r (114)
      1x s (115)
      1x u (117)
      1x y (121)
      

      【讨论】:

        猜你喜欢
        • 2014-09-19
        • 2020-06-19
        • 2023-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-03
        相关资源
        最近更新 更多