【问题标题】:Counting the number of times words in an array that are within a sentence计算数组中单词在句子中的次数
【发布时间】:2019-09-16 17:23:19
【问题描述】:

我正在编写代码来计算数组中每个单词出现的次数以及出现的所有单词的总数。我设法创建了一个数组,允许用户添加他们希望检查的多个单词。但是,我正在努力寻找一种方法来单独计算每个单词在句子中出现的次数(我只能让它对数组的第一个元素起作用)。

我尝试了一个 for 循环,完成后它将移动到数组中的下一个元素,但它不会为下一个元素再次开始 for 循环,而是结束代码块。

int occurences = 0;

string[] words = new string[_wordCount];

for (int i = 0; i < words.Length; i++)
{
    Console.WriteLine("Type in the censored words you wish to be counted: ");
    words[i] = Console.ReadLine();

    if (_sentence.Contains(words[i]))
    {
        occurences++;
    }

    if (i > words.Length)
    {
        i++;
    }
}

Console.WriteLine("Number of censored word occurences: " + occurences);
return occurences;

【问题讨论】:

    标签: c#


    【解决方案1】:

    您只需要像这样单独计算每个单词的出现次数:

    int i, j, woccurence, occurences = 0;
    string[] words, details = new string[_wordCount];
    for (i = 0; i < words.Length; i++)
    {
        Console.WriteLine("Type in the censored words you wish to be counted: ");
        words[i] = Console.ReadLine();
        woccurence = 0;
        details = _sentence.Split(' ');
        for (j = 0; j < details.Length; j++)
            if (details[j] == words[i])
                woccurences++;
        Console.WriteLine("Number of censored word occurences: " + woccurences);
        occurences += woccurences;
    }
    Console.WriteLine("Number of total censored words occurences: " + occurences);
    return occurences;
    

    详情

    在循环的每个循环中,您使用woccurence 计算单词从头开始出现的次数并将其打印出来,然后将此值添加到总数中occurrence

    【讨论】:

    • 非常感谢您,此代码似乎按预期工作。但是,如果问的不是太多,您能否介绍一下代码的工作原理,以便我可以从中吸取教训以及我犯的任何错误?
    • 现在检查我的答案。这够了吗?
    • 是的!再次感谢,不胜感激。
    • 现在代码可以给你句子中出现的次数。
    • 是的,这计算了一句话内的数量,谢谢。需要什么细节?为了确保它遗漏了空格和标点符号?
    【解决方案2】:

    如果句子由空格分隔的单词组成,您可以使用 string.split 将其制成一个数组,然后您可以遍历该数组。

    var sentenceArray = _sentence.Split(new Char [] {' '});
    

    然后在你的主要单词循环中循环遍历句子数组。

    【讨论】:

      【解决方案3】:

      我没有看到 _sentence 或 _wordCount 的设置位置,但请告诉我您是否想到了这一点。

      警告:我假设用户会在提示时输入每个单词,单词之间有一个空格。您可能需要处理用户使用过多空格、逗号等的情况。

          static int GetWords()
          {
             int occurences = 0;
             int _wordCount = 0;
      
             string _sentence = "The quick brown fox jumped over the lazy dog.";
             string[] words = new string[_sentence.Length];
      
             Console.WriteLine("Type in the censored words you wish to be counted: ");
             string censoredWordString = Console.ReadLine();
             string[] censoredWords = censoredWordString.Split(' ');
      
             for (int i = 0; i < censoredWords.Length; i++)
             {                  
                 if (_sentence.Contains(censoredWords[i]))
                 {
                    occurences++;
                 }                       
             }
      
             Console.WriteLine("Number of censored word occurences: " + occurences);
      
             return occurences;
           }
      

      【讨论】:

        【解决方案4】:

        你可以试试这个:

        int occurences = 0;
        
        string sentence = "This is a test sentence. This sentence is test. This sentence do nothing.";
        
        var sentenceWords = new string(sentence.Where(c => !char.IsPunctuation(c)).ToArray()).Split(' ');
        
        var wordsFound = new Dictionary<string, int>();
        
        Console.WriteLine("Sentence = " + sentence);
        
        while ( true)
        {
          Console.WriteLine(Environment.NewLine);
          Console.WriteLine("Type in a censored word you wish to be counted (enter empty to end): ");
          string input = Console.ReadLine();
          if ( input == "" ) break;
          int count = sentenceWords.Count(word => word.ToLower() == input.ToLower());
          if ( count == 0 )
          {
            Console.WriteLine("Can't find \"" + input + "\".");
          }
          else
          {
            Console.WriteLine("Found " + count + " occurences of \"" + input + "\".");
            if ( !wordsFound.ContainsKey(input) )
              wordsFound.Add(input, count);
            occurences += count;
          }
        }
        
        Console.WriteLine(Environment.NewLine);
        Console.WriteLine("Number of total censored words occurences: " + occurences);
        foreach ( var item in wordsFound)
          Console.WriteLine("     " + item.Key + ": " + item.Value);
        
        Console.ReadKey();
        

        【讨论】:

          【解决方案5】:

          您只能使用 LINQ 实现这一目标

          int totalWords = 0;
          var sentence = "Don't cry because it's over, smile because it happened";
          
          sentence.ToLower().Split(' ').GroupBy(x => x).ToList().ForEach(x=> {
              totalWords += x.Count();
              Console.WriteLine($"{x.Key}: {x.Count()}");
          });
          
          Console.WriteLine($"Total words: {totalWords}");
          

          首先我们使用ToLower() se我们可以去掉lowers和uppers

          然后我们用.Split(' ')空格分割

          现在我们用GroupBy(x=&gt;x)按每个单词分组

          我们需要使用ToList() 来转换IGrouping&lt;T&gt;,这样我们就可以使用ForEach 来迭代结果

          最后我们打印得到Key的结果,它引用了分组的​​对象,并使用Count()得到组包含的数量

          【讨论】:

          • 感谢您的回复。据我所知,我需要用字符串数组单词替换 x 吗?正如我在代码中创建的“String[] words = new string[_wordCount]”?
          • 其实只需要将sentence变量内容替换成你要分析的句子即可。 x 是 lambda 表达式的一部分
          • 不要在 LINQ 中使用 ToList().ForEach()
          • 我需要 ToList(),因为我不能 foreach 一个 IGrouping,替换它的最佳选择是什么?
          【解决方案6】:

          就个人而言,我会使用字典。特别是使用stringint&lt;key, value&gt;

          int occurances = 0;
          string[] words = new string[_wordCount];
          var results = new Dictionary<string, int>();
          var splitSentence = _sentence.Split(' ').ToArray();
          
          
          for(int i = 0; i < words.Length; i++)
          {
              Console.WriteLine("Type in the censored words you wish to be counted: ");
              words[i] = Console.ReadLine();
          
              if(_sentence.Contains(words[i]))
              {
                  if(!results.ContainsKey(words[i]))
                  {
                      results.Add(words[i], 0);
                  }
          
                  for(var j = 0; j < splitSentence.Length; j++)
                  {
                      if(splitSentence[j] == words[i])
                      {
                           results[words[i]]++;
                           occurances++;
                      }
                  }
              }
          }
          

          对于字典,第一个“参数”必须是唯一的,因此任何时候再次出现一个单词,您只需首先检查该键是否存在,它只会添加到计数中(@987654326 中的 value @对)。

          【讨论】:

          • "你将迭代 2" 这不是真的,只是当 i 大于 words.Length 时,即永远不会因为内部循环 (i
          • 我猜是一时的阅读障碍。无论如何,这是不必要的,我将其从答案中删除。
          • 我怎样才能分别计算多个单词。例如,句子输入是“我有一些奶酪,奶酪很好”,选择的词是奶酪和好。我希望输出是“奶酪:2,好:1,总计:3”。我将如何实现这一目标?
          • 因此,在这种情况下,您将拥有一个字典,其中键为 cheesegood,字典的值分别为 13。因此,如果您想查看特定单词出现了多少次,您只需要执行var someInt = results["cheese"]。 (并将"cheese" 替换为您要查找的任何单词。)虽然我会建议@terrencep 的建议,并用空格分隔_sentence。我会更新我的答案
          • @Drilzone 更新了我的答案
          【解决方案7】:

          使用 LINQ 和正则表达式:

          var sentence = "now is the time for all good men to come, to the aid of their country.";
          var words = new[] { "time", "to" };
          
          var wordsHS = words.ToHashSet();
          var wordRE = new Regex(@"\w+", RegexOptions.Compiled);
          var wordCounts = wordRE.Matches(sentence).Cast<Match>().Select(m => m.Value)
                                 .Where(w => wordsHS.Contains(w))
                                 .GroupBy(w => w)
                                 .Select(wg => new { Word = wg.Key, Count = wg.Count() })
                                 .ToList();
          var total = wordCounts.Sum(wc => wc.Count);
          

          【讨论】:

            猜你喜欢
            • 2021-04-13
            • 1970-01-01
            • 2015-08-18
            • 2012-01-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多