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

时间:2013-06-27 19:03:54

标签: c# string counter

我有一个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);

            }

下面是一些线条的样子:

一包硬币

一个siog白兰地

一包硬币

一包硬币

Cath Shield

破烂的卷轴

所以我试图做的是计算有3行硬币包。但我需要做到这一点,它可以成为一切,这是一个巨大的下降列表。所以不能添加所有的em,需要太长时间

修改

    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寻求者掉了一杯白兰地。

[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寻求者死了

5 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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;
    }
}

您的字符串是字典的键,每次出现的次数都是值。

(免责声明:未测试代码;可能需要进行细微调整。)

答案 2 :(得分: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;
         }
     }
}

答案 3 :(得分:0)

如果你试图在所有的数组中找到多少个字符串匹配(我的意思是 - “字符串1”出现2次 - 而 - “字符串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
}

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

答案 4 :(得分: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