c#从文本文件中计算相同的字符串

c# counting identical strings from text file

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

这是我的密码。这是我被困的第二个if声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        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);

            }

下面是一些线条的样子:

一袋硬币

西奥白兰地酒

一袋硬币

一袋硬币

卡斯盾

破烂的卷轴

所以我要做的就是数数,有三行硬币。但我要做的是让它成为一切,有一个巨大的下拉列表。所以不能全部加起来,要花太长时间

编辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    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]西奥人丢了一袋硬币。

[01:09:55]siog seeker掉了一瓶siog白兰地。

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

[01:09:55]您获得3687564点体验积分。(1638917营地奖金)

[01:10:31]你施展了一个较小的清醒爆发法术!

[01:10:31]你击中SIOG探索者造成424(+18)点伤害!

[01:10:31]西奥人丢了一袋硬币。

[01:10:31]你挑选了18块银币和88块铜币。

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


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

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

要读取这些值,只需遍历字典,使用示例列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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查询。

1
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次。

根据评论更新

在你的情况下应该可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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);
}


我喜欢用字典来做这个。

1
2
3
4
5
6
7
8
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;
    }
}

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

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


我想这就是你想要的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
         }
     }
}


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

1
2
3
4
5
6
   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");
   }

输出如下:

1
2
3
stringOne occured 3 times
stringTwo occured 2 times
stringThree occured 1 times


如果要查找所有行数组中匹配的字符串数(我的意思是"string one"出现2次,而"string two"出现4次),请在foreach外创建一个字典,在foreach内创建第一个字符串,请将此放置:

1
2
3
4
5
6
7
8
9
10
11
12
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
}

重复的每个字符串都将在字典的值中更新(字典中会记录所有字符串及其出现的次数),您可以使用该值检查某个字符串出现的次数。