Подсчет количества слов в С#

Я пытаюсь подсчитать количество слов из богатого текстового поля в С#, код, который у меня ниже, работает только в том случае, если это одна строка. Как это сделать, не полагаясь на регулярное выражение или какие-либо другие специальные функции.

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 ());

Ответ 1

Поскольку вас интересует только количество слов, и вам нет дела до отдельных слов, String.Split можно было бы избежать. String.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++;
}

Этот код должен работать лучше в тех случаях, когда у вас есть несколько пробелов между каждым словом, вы можете проверить код в Интернете.

Ответ 2

char[] delimiters = new char[] {' ', '\r', '\n' };
whole_text.Split(delimiters,StringSplitOptions.RemoveEmptyEntries).Length;  

Ответ 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

Посмотрите на свойство Lines, указанное в комментарии @Jay Riggs, а также эту перегрузку String.Split, чтобы сделать код намного проще. Тогда самым простым подходом было бы перебрать каждую строку в свойстве Lines, называть String.Split на нем и добавить длину массива, который он возвращает, к счету выполнения.

EDIT: Также есть причина, по которой вы используете RichTextBox вместо TextBox с Multiline, установленным на True?

Ответ 6

Ваш подход находится на правильном пути. Я бы сделал что-то вроде передачи свойства text 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;
}

Ответ 7

Мы использовали адаптированную форму ответа Йоши, где мы исправили ошибку, в которой он не учитывал бы последнее слово в строке, если после него не было белого пространства:

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;
}

Ответ 8

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;
}

Ответ 9

Это должно работать

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

Ответ 10

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();
 }

Ответ 11

Вы также можете сделать это таким образом! Добавьте этот метод к вашим методам расширения.

   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();