【问题标题】:Counting number of words in C#计算C#中的单词数
【发布时间】:2012-01-09 06:07:55
【问题描述】:

我正在尝试计算 C# 中富文本框中的单词数,下面的代码仅在它是单行时才有效。我如何在不依赖正则表达式或任何其他特殊功能的情况下做到这一点。

string whole_text = richTextBox1.Text;
string trimmed_text = whole_text.Trim();
string[] split_text = trimmed_text.Split(' ');
int space_count = 0;
string new_text = "";

foreach(string av in split_text)
{
    if (av == "")
    {
        space_count++;
    }
    else 
    { 
        new_text = new_text  + av + ",";
    }
}

new_text = new_text.TrimEnd(',');
split_text = new_text.Split(',');
MessageBox.Show(split_text.Length.ToString ());

【问题讨论】:

  • 这里有一个作业提示:查看 RichTextBox 的 Lines 属性以检索 RTB 的内容。

标签: c#


【解决方案1】:
char[] delimiters = new char[] {' ', '\r', '\n' };
whole_text.Split(delimiters,StringSplitOptions.RemoveEmptyEntries).Length;  

【讨论】:

  • 这将是我在回答中提到的“有更好的方法来做到这一点”部分;)+1。
  • +1 表示RemoveEmptyEntries。如果一行中有多个空格字符会有所不同。
  • 速度快,内存占用少。优化非常棒。
  • 好主意。
  • 还应该在分隔符中添加制表符'\t'。
【解决方案2】:

由于您只对字数感兴趣,而不关心单个单词,因此可以避免使用String.SplitString.Split 很方便,但它不必要地生成(可能)大量的String 对象,这反过来又给垃圾收集器带来了不必要的负担。对于文本中的每个单词,都需要实例化一个新的 String 对象,然后很快就会收集起来,因为您没有使用它。

对于家庭作业,这可能无关紧要,但如果您的文本框内容经常更改并且您在事件处理程序中进行此计算,那么简单地手动迭代字符可能更明智。如果你真的想使用String.Split,那么推荐使用Yonix 这样更简单的版本。

否则,使用类似这样的算法:

int wordCount = 0, index = 0;

// skip whitespace until first word
while (index < text.Length && char.IsWhiteSpace(text[index]))
    index++;

while (index < text.Length)
{
    // check if current char is part of a word
    while (index < text.Length && !char.IsWhiteSpace(text[index]))
        index++;

    wordCount++;

    // skip whitespace until next word
    while (index < text.Length && char.IsWhiteSpace(text[index]))
        index++;
}

此代码应该更适合每个单词之间有多个空格的情况,您可以测试code online

【讨论】:

  • 有人能解释一下为什么这个答案比其他答案更快吗?比如: var count = text.Count(x => x == ' ');或类似: var count = Math.Ceiling((double) text.Length / 6);其中 6 是荷兰语的平均字长 + 1 表示空格。
  • @Blackunknown:关键不是它不快,而是正确:1)单词之间可以有多个空白字符,甚至可以在文本的开头/结尾使用空白字符, 2) 空白字符也可以是制表符、换行符和回车符,3) 除以平均字长在很多情况下显然会给你一个近似的结果,而在很多其他情况下却是完全错误的结果。
  • @Blackunknown:但在 C# 中确实比 String.Split 更快,因为 String.Split 为每个单词分配堆空间并将字符复制到那里。因此,如果您有一个包含 1000 个单词的文本,String.Split 将创建 1000 个字符串实例,将整个文本复制到那里,即使您实际上根本不需要这些字符串。然后垃圾收集器必须在稍后的某个时间收集它们,这也引入了延迟。对于一个小的家庭作业,这也可能没问题,只要学生意识到这些影响。
【解决方案3】:

有一些更好的方法可以做到这一点,但根据你所拥有的,尝试以下方法:

string whole_text = richTextBox1.Text;
string trimmed_text = whole_text.Trim();

// new line split here
string[] lines = trimmed_text.Split(Environment.NewLine.ToCharArray());

// don't need this here now...            
//string[] split_text = trimmed_text.Split(' ');

int space_count = 0;
string new_text = "";

现在创建两个 foreach 循环。每行一个,一个用于计算行内的单词。

foreach (string line in lines)
{
    // Modify the inner foreach to do the split on ' ' here
    // instead of split_text
    foreach (string av in line.Split(' '))
    {
        if (av == "")
        {
            space_count++;
        }
        else
        {
            new_text = new_text + av + ",";
        }
    }
}

new_text = new_text.TrimEnd(',');

// use lines here instead of split_text
lines = new_text.Split(',');
MessageBox.Show(lines.Length.ToString());
}

【讨论】:

    【解决方案4】:

    这是我刚参加的一个电话筛选面试问题(由一家位于加利福尼亚州的大公司提出,该公司销售以字母“i”开头的各种设备),我想我是在我下线后收到的…… ,我写了这个。我希望我能够在面试时做到这一点..

    static void Main(string[] args)
    {
        Debug.Assert(CountWords("Hello world") == 2);
        Debug.Assert(CountWords("    Hello world") == 2);
        Debug.Assert(CountWords("Hello world    ") == 2);
        Debug.Assert(CountWords("Hello      world") == 2);
    }
    
    public static int CountWords(string test)
    {
        int count = 0;
        bool wasInWord = false;
        bool inWord = false;
    
        for (int i = 0; i < test.Length; i++)
        {
            if (inWord)
            {
                wasInWord = true;
            }
    
            if (Char.IsWhiteSpace(test[i]))
            {
                if (wasInWord)
                {
                    count++;
                    wasInWord = false;
                }
                inWord = false;
            }
            else
            {
                inWord = true;
            }
        }
    
        // Check to see if we got out with seeing a word
        if (wasInWord)
        {
            count++;
        }
    
        return count;
    }
    

    【讨论】:

      【解决方案5】:

      查看@Jay Riggs 评论中提到的Lines 属性以及this overload of String.Split,以使代码更简单。那么最简单的方法是遍历Lines 属性中的每一行,在其上调用String.Split,并将它返回的数组的长度添加到运行计数中。

      编辑:另外,您是否有任何理由使用 RichTextBox 而不是将 Multiline 设置为 True 的 TextBox?

      【讨论】:

        【解决方案6】:

        我使用extension method 来获取字符串中的字数。但是请注意,双空格会打乱计数。

            public static int CountWords(this string line)
            {
                var wordCount = 0;
                for (var i = 0; i < line.Length; i++)
                    if (line[i] == ' ' || i == line.Length - 1)
                        wordCount++;
                return wordCount;
            }
        }
        

        【讨论】:

          【解决方案7】:

          您的方法是正确的。我会做类似的事情,将richTextBox1 的文本属性传递给方法。但是,如果您的富文本框正在格式化 HTML,这将不准确,因此您需要在运行字数统计之前去除所有 HTML 标记:

          public static int CountWords(string s)
              {
              int c = 0;
              for (int i = 1; i < s.Length; i++)
              {
                  if (char.IsWhiteSpace(s[i - 1]) == true)
                  {
                  if (char.IsLetterOrDigit(s[i]) == true ||
                      char.IsPunctuation(s[i]))
                  {
                      c++;
                  }
                  }
              }
              if (s.Length > 2)
              {
                  c++;
              }
              return c;
          }
          

          【讨论】:

            【解决方案8】:

            我们使用了 Yoshi 答案的改编形式,修复了如果字符串后面没有空格,它不会计算字符串中最后一个单词的错误:

            public static int CountWords(string test)
            {
              int count = 0;
              bool inWord = false;
            
              foreach (char t in test)
              {
                if (char.IsWhiteSpace(t))
                {
                  inWord = false;
                }
                else
                {
                  if (!inWord) count++;
                  inWord = true;
                }
              }
              return count;
            }
            

            【讨论】:

              【解决方案9】:
              using System.Collections;
              using System;
              class Program{
              public static void Main(string[] args){
                      //Enter the value of n
                      int n = Convert.ToInt32(Console.ReadLine());
                      string[] s = new string[n];
                      ArrayList arr = new ArrayList();
                      //enter the elements
                      for(int i=0;i<n;i++){
                          s[i] = Console.ReadLine();
                      }
                      string str = "";
                      //Filter out duplicate values and store in arr
                      foreach(string i in s){
                          
                          if(str.Contains(i)){
                
                              }else{
                                  arr.Add(i);
                              }
                              str += i;
                      }
                      //Count the string with arr and s variables
                      foreach(string i in arr){
                          int count = 0;
                          foreach(string j in s){
                              if(i.Equals(j)){
                                  count++;
                              }
                          }
                          Console.WriteLine(i+" - "+count);
                      }
                  }
              }
              

              【讨论】:

              • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
              【解决方案10】:
              public static int WordCount(string str)
              {        
                  int num=0;
                  bool wasInaWord=true;;
              
                  if (string.IsNullOrEmpty(str))
                  {
                      return num;
                  }
              
                  for (int i=0;i< str.Length;i++)
                  {
                      if (i!=0)
                      {
                          if (str[i]==' ' && str[i-1]!=' ')
                          {
                              num++;
                              wasInaWord=false;
                          }
                      } 
                          if (str[i]!=' ')
                          {
                              wasInaWord=true;                
                          }
                  }
                  if (wasInaWord)
                  {
                      num++;
                  }
                  return num;
              }
              

              【讨论】:

              • 请对答案中的代码提供一些解释。
              【解决方案11】:
              class Program
               {
                  static void Main(string[] args)
                  {
                      string str;
                      int i, wrd, l;
                      StringBuilder sb = new StringBuilder();
              
                      Console.Write("\n\nCount the total number of words in a string 
                      :\n");
                      Console.Write("--------------------------------------------------- 
                      ---\n");
                      Console.Write("Input the string : ");
                      str = Console.ReadLine();
              
                      l = 0;
                      wrd = 1;
              
                      foreach (var a in str)
                      {
                          sb.Append(a);
                          if (str[l] == ' ' || str[l] == '\n' || str[l] == '\t')
                          {
                              wrd++;
                          }
                          l++;
                      }
              
                      Console.WriteLine(sb.Replace(' ', '\n'));
                      Console.Write("Total number of words in the string is : {0}\n", 
                      wrd);
                      Console.ReadLine();
               }
              

              【讨论】:

                【解决方案12】:

                这应该可以工作

                input.Split(' ').ToList().Count;
                

                【讨论】:

                  【解决方案13】:

                  这可以显示一行中的单词数

                  string line = Console.ReadLine();
                  string[] word = line.Split(' ');
                  Console.WriteLine("Words " + word.Length);
                  

                  【讨论】:

                    【解决方案14】:

                    你也可以这样做!!将此方法添加到您的扩展方法中。

                       public static int WordsCount(this string str)
                        {
                            return Regex.Matches(str, @"((\w+(\s?)))").Count;
                        }
                    

                    然后这样称呼它。

                      string someString = "Let me show how I do it!";
                      int wc = someString.WordsCount();
                    

                    【讨论】:

                    • 如果我们有多个空格或单词之间有“\r\n”换行符,这会给出错误的答案。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-04-19
                    • 2012-10-04
                    • 1970-01-01
                    相关资源
                    最近更新 更多