【问题标题】:Sort lines of strings by number of occurrences按出现次数对字符串行排序
【发布时间】:2016-08-16 03:47:50
【问题描述】:

我仍处于学习 C# 的初级阶段,在按文件中出现的次数对字符串进行排序时遇到了问题。

到目前为止,这是我的代码:

string[] listLines = System.IO.File.ReadAllLines(@"F:\VS\AI.xls");

Array.Sort<string>(listLines); // sort alfabeticaly
System.Console.WriteLine("History of experienced feeds:");

/*
foreach (var line in listLines) //loop to return lines in alfabetical order
{
    Console.WriteLine("\t" + line);
}
*/

// counts occurrences
var dict = new Dictionary<string, int>();

foreach (var value in listLines)
{
    if (dict.ContainsKey(value))
        dict[value]++;
    else
        dict[value] = 1;
}

foreach (var pair in dict)
    Console.WriteLine("{1} times {0}", pair.Key, pair.Value);

System.Console.WriteLine("");
System.Console.WriteLine("Press Enter to see most common feeds:");

Console.ReadKey();

/* Finds duplicates and sorts them alphabetically */
System.Console.WriteLine("Most common:");
var duplicates = listLines.GroupBy(i => i) 
                          .Where(g => g.Count() > 1)
                          .Select(g => g.Key);

foreach (var d in duplicates)
    Console.WriteLine(d);

如您所见,这可以分为两部分。首先,我计算每个字符串以获取它们出现的次数。然后,我只显示出现多次的那些 - 按字母顺序。

我需要的是介于两者之间的东西:一种显示重复字符串的方法,但按从最少出现到最多出现的顺序显示。

您能指导我以正确的方式实现这一目标吗?

谢谢,

【问题讨论】:

    标签: c# string sorting duplicates


    【解决方案1】:

    将此添加到您的代码中:

    foreach(var str in dict.Where(p => p.Value > 1).OrderBy(p => p.Value).Select(p => p.Key))
      Console.WriteLine(str);
    

    【讨论】:

    • 您需要在填充字典后添加该行。你的字典被填充了吗?
    • 我认为是因为代码的第二部分有效。
    • 我添加了一个子句,只显示出现次数超过 1 次的字符串。
    【解决方案2】:
    var strings = new string[] { "a", "a", "b", "b", "b", "c" };
    var mostPopular = strings
        .GroupBy(s => s) //removed unnecessary count
        .OrderByDescending(g => g.Count());
    mostPopular.ToList().ForEach(g => Console.WriteLine("{0}: {1}", g.Key, g.Count()));
    

    GroupBy 所做的是选择IGrouping&lt;string,string&gt; 中的三个。

    每个分组包含一个Key(我们分组的值)和一组字符串(与该键匹配的值。)

    一个键是“a”,那么分组元素的集合是[“a”,“a”],所以Count是2。 另一个键是 "b",分组元素的集合是 ["b", "b", "b"] 所以Count 是 3。

    这是一个字面解释,但我认为它听起来更复杂和令人困惑。我更喜欢把它想象成类似于

    SELECT s, count(*) from strings GROUP BY s ORDER BY count(*) DESC
    

    【讨论】:

    • 行得通!你能用几句话写出这里到底发生了什么吗?谢谢!
    • 我从字符串列表开始,然后使用 Linq GroupBy。这将创建一个分组,该分组具有一个键(原始字符串)和按该键分组的项目的集合。这样我们就可以查看与该键匹配的项目数。大致相当于SELECT s, count(*) from strings GROUP BY s ORDER BY count(*) DESCENDING
    • 非常感谢斯科特。你的答案很完美,你的代码就是我想要的。感谢您的解释,我将研究它以便将来能够重新创建解决方案。谢谢!
    • 我从GroupBy 中删除了一个细节并用评论标记了它。这是不必要的 - 你可以看出,如果它被删除,它不会改变任何东西。
    【解决方案3】:
    foreach(KeyValuePair kvp in dict.Where(x => x.Value > 1) 
                                    .OrderByDescending(x => x.Value)) 
          Console.WriteLine(kvp.Key);
    

    【讨论】:

    • 我认为您需要添加 Where 子句以显示出现 > 1 的行。
    【解决方案4】:

    Linq 来救援 :)

    new [] { "A", "Be", "D", "C", "Be", "C", "D", "C"}
    .GroupBy(v => v)
    .Select(g => new { Value = g.Key, Count = g.Count() })
    .OrderByDescending(g => g.Count)
    .Select(g => g.Value)
    

    给予:

    C 
    Be 
    D 
    A 
    

    【讨论】:

      猜你喜欢
      • 2014-12-12
      • 2017-02-08
      • 2021-04-16
      • 2019-10-17
      • 2017-02-21
      • 2021-03-01
      • 2023-03-11
      • 1970-01-01
      • 2011-05-16
      相关资源
      最近更新 更多