3

我有一个foreach声明,我从一个文本文件中浏览了几行,在那里我修剪并整理了我需要的行。我想要做的是计算一个相同的字符串出现了多少次。我该怎么做呢?

这是我的代码。if这是我卡住的第二个陈述:

        foreach (string line in lines.Where(l => l.Length >= 5))
        {
            string a = line.Remove(0, 11);

            if ((a.Contains(mobName) && a.Contains("dies")))
            {

                mobDeathCount++;
            }
            if (a.Contains(mobName) && a.Contains("drops"))
            {
                string lastpart = a.Substring(a.LastIndexOf("drops"));
                string modifiedLastpart = lastpart.Remove(0, 6);

            }

下面是一些行的样子:

一袋硬币

西格白兰地

一袋硬币

一袋硬币

凯丝盾

破烂的卷轴

所以我想要做的是数一数有 3 行一袋硬币。但我需要让它成为一切,有一个巨大的下拉列表。所以不能添加所有的时间,会花费太长时间

编辑

    private static void Main()
    {
        int mobDeathCount = 1;
        int lootCheckCount = 1;

        string[] lines =
            System.IO.File.ReadAllLines(@"C:\Users\Michael\Documents\Electronic Arts\Dark Age of Camelot\chat.log");
        Console.WriteLine(
            "Enter which mob you want to see, remember to include the, for an example; The siog seeker, remember to start with a capital T");
        string mobName = Console.ReadLine();


        foreach (string line in lines.Where(l => l.Length >= 5))
        {




            string a = line.Remove(0, 11);

            if ((a.Contains(mobName) && a.Contains("dies")))
            {

                mobDeathCount++;
            }
            if (a.Contains(mobName) && a.Contains("drops"))
            {
                string lastpart = a.Substring(a.LastIndexOf("drops"));
                string modifiedLastpart = lastpart.Remove(0, 6);

               var lineCountDict = modifiedLastpart.GroupBy(x => x).Where(x => x.Count() > 1).ToDictionary(x => x.Key, x => x.Count());
               foreach (var val in lineCountDict)
               {
                   Console.WriteLine(val.Key + " - " + val.Value);
               }

新线路;

[01:09:55] siog 搜寻者丢下一袋硬币。

[01:09:55] siog 搜寻者丢下 siog 白兰地。

[01:09:55] siog 探索者死了!

[01:09:55] 你获得 3,687,564 经验值。(1,638,917 营地奖励)

[01:10:31] 你施放了一个次级祛魅喷发法术!

[01:10:31] 你击中了 siog 搜寻者,造成 424 (+18) 伤害!

[01:10:31] siog 搜寻者丢下一袋硬币。

[01:10:31] 你捡起 18 块银和 88 块铜。

[01:10:31] siog 探索者死亡

4

5 回答 5

11

您可以使用 LINQ 获取重复行数。这将创建一个字典,其中包含作为 的字符串key以及该字符串作为 出现的次数value

var lineCountDict = lines.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count());

要读出值,只需遍历字典所以,使用您的示例列表

List<String> lines = new List<string>()
     { 
         "a bag of coins",
         "a siog brandy",
         "a bag of coins",
         "a bag of coins",
         "the Cath Shield",
         "a tattered scroll"
     };

var lineCountDict = lines.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count());

foreach (var val in lineCountDict)
{
     Console.WriteLine(val.Key + " - " + val.Value);
}

这将输出每个字符串以及它出现的次数,包括那些只出现一次的字符串。如果您只想要那些重复的,您可以通过添加Where子句来修改 LINQ 查询

var lineCountDict = lines.GroupBy(x => x).Where(x => x.Count() > 1).ToDictionary(x => x.Key, x => x.Count());

然后,该字典将仅包含您示例 ( a bag of coins) 中列表中的一项,键是a bag of coins,值是,3因为它出现了 3 次。

根据评论更新

这应该适用于您的情况

List<string> modifiedList = new List<string>();
int numberOfDrops = 0;

foreach (string line in lines.Where(l => l.Length >= 5))
{
     string ad = line.Remove(0, 11);

     if ((ad.Contains(mobName) && ad.Contains("dies")))
     {
        mobDeathCount++;
     }
     if (ad.Contains(mobName) && ad.Contains("drops"))
     {
         string lastpart = ad.Substring(ad.LastIndexOf("drops"));
         string modifiedLastpart = lastpart.Remove(0, 6);
         modifiedList.Add(modifiedLastpart);
         numberOfDrops++;
     }

}

double deathDropRatio = (double)mobDeathCount / (double)numberOfDrops;

var lineCountDict = modifiedList.GroupBy(x => x).Where(x => x.Count() > 1).ToDictionary(x => x.Key, x => x.Count());

foreach (var val in lineCountDict)
{
   Console.WriteLine(val.Key + " - " + val.Value);
}
于 2013-06-27T19:11:49.743 回答
3

我喜欢为此使用字典。

Dictionary<string, int> dict = new Dictionary<string, int>();
foreach (string s in yourStringList) {
    if (dict.ContainsKey(s)) {
        dict[s] = ++dict[s];
    } else {
        dict[s] = 1;
    }
}

你的字符串是字典的键,每个出现的次数就是值。

(免责声明:未测试代码;可能需要稍作调整。)

于 2013-06-27T19:14:48.420 回答
1

我认为这就是你想要的:

Dictionary<string, int> dropsDict = new Dictionary<string, int>();    

foreach (string line in lines.Where(l => l.Length >= 5))
{
     string a = line.Remove(0, 11);

     if ((a.Contains(mobName) && a.Contains("dies")))
     {
         mobDeathCount++;
     }

     if (a.Contains(mobName) && a.Contains("drops"))
     {
         string lastpart = a.Substring(a.LastIndexOf("drops"));
         string modifiedLastpart = lastpart.Remove(0, 6);

         if (dropsDict.ContainsKey(modifiedLastpart)) 
         {
             dropsDict[modifiedLastpart] = dropsDict[modifiedLastpart]++;
         } 
         else 
         {
             dropsDict[modifiedLastpart] = 1;
         }
     }
}
于 2013-06-27T19:28:17.037 回答
0

如果您试图在所有行数组中查找有多少字符串匹配(我的意思是 - “字符串一”出现 2 次 - 并且 - “字符串二”出现 4 次),请在 foreach 之外创建一个字典,然后在里面创建一个字典foreach 放置这个:

Dictionary<string, int> same = new Dictionary<string, int>();

foreach (string line in lines)
{
      if (same.ContainsKey(line))
          ++same[line];
      else
          same.Add(line, 1);

      //......
      //do your other stuff
}

每个重复的字符串都将在字典的值中更新(字典内将记录所有字符串以及它们出现的次数),您可以检查某个字符串出现了多少次。

于 2013-06-30T22:19:19.037 回答
0

也许这可以帮助你,这是一段计算集合中所有重复字符串的代码。您必须修改它以满足您的需要,但希望您指出这一点。

   var allStrings = new  List<string>{"stringOne", "stringOne", "stringTwo", "stringOne", "stringThree", "stringTwo"};
   var allStringsGrouped = allStrings.GroupBy(i => i);
   foreach (var group in allStringsGrouped)
   {
       System.Diagnostics.Debug.WriteLine(group.Key +" occured " + group.Count() + " times");
   }

输出如下:

stringOne occured 3 times
stringTwo occured 2 times
stringThree occured 1 times
于 2013-07-03T12:17:29.077 回答