C#循环遍历列表以查找字符数

Posted

技术标签:

【中文标题】C#循环遍历列表以查找字符数【英文标题】:C# looping through a list to find character counts 【发布时间】: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","") 【参考方案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)

【讨论】:

以上是关于C#循环遍历列表以查找字符数的主要内容,如果未能解决你的问题,请参考以下文章

在循环中按索引遍历列表列表,以重新格式化字符串

C#中如何用for循环遍历List<类>?

循环遍历字符串列表

c#用foreach遍历数组、列表时是直接获得数据元素,而foreach哈希表时,为啥获得的是命名空间名??

foreach 循环不会遍历列表中的所有项目 - C#

Python列表list操作-遍历查找增加删除修改排序