2012-01-09 23 views
9

Próbuję policzyć liczbę słów z bogatego pola tekstowego w C# kod, który mam poniżej działa tylko, jeśli jest to pojedyncza linia. Jak to zrobić bez polegania na regex lub jakichkolwiek innych specjalnych funkcjach.Zliczanie liczby słów w 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()); 
+5

Oto wskazówka dla swojej pracy domowej: patrzeć na [Lines] (http://msdn.microsoft.com/en-us/library/system.windows. forms.textboxbase.lines.aspx) właściwość RichTextBox do pobierania zawartości RTB. –

Odpowiedz

15

Ponieważ jesteś zainteresowany tylko w wyrazów, i nie dbam o poszczególnych słów, String.Split można by uniknąć. String.Split jest przydatny, ale niepotrzebnie generuje (potencjalnie) dużą liczbę obiektów String, co z kolei powoduje niepotrzebne obciążenie odnika. Dla każdego słowa w tekście należy utworzyć instancję nowego obiektu String, a następnie szybko go zebrać, ponieważ go nie używasz.

Jeśli chodzi o zadanie domowe, może to nie mieć znaczenia, ale jeśli zawartość pola tekstowego często się zmienia i wykonujesz te obliczenia wewnątrz procedury obsługi zdarzeń, może być rozsądniej po prostu powtórzyć poszczególne znaki ręcznie. Jeśli naprawdę chcesz używać String.Split, wybierz prostszą wersję, na przykład Yonix.

W przeciwnym razie, należy użyć algorytmu podobnego do tego:

var text = richTextBox1.Text.Trim(); 
int wordCount = 0, index = 0; 

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

Kod ten powinien działać lepiej w przypadkach, gdy masz wiele przestrzenie między każdym słowem.

0

Twoje podejście jest na dobrej drodze. Zrobiłbym coś takiego, przekazując właściwość text richTextBox1 do metody. To jednak nie będą dokładne, jeśli jest bogaty tekstowe formatowanie HTML, więc trzeba się rozebrać żadnych tagów HTML przed uruchomieniem słowo liczyć:

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

Zapraszamy do obejrzenia nieruchomości Lines mowa w @ Komentarz Jaya Riggsa, wraz z this overload of String.Split, aby kod był znacznie prostszy. Najprostszym rozwiązaniem byłoby zapętlenie każdej linii we właściwości Lines, wywołanie na niej linii String.Split i dodanie długości tablicy, która powraca do liczby uruchomień.

EDYCJA: Czy istnieje jakikolwiek powód, dla którego używasz RichTextBox zamiast TextBox z Multiline ustawiona na True?

4

Są lepsze sposoby, aby to zrobić, ale w zgodzie z tym, co masz, spróbuj wykonać następujące czynności:

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 = ""; 

teraz zrobić dwa pętla foreach. Jedna dla każdej linii i druga dla zliczania słów w liniach.

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()); 
} 
24
char[] delimiters = new char[] {' ', '\r', '\n' }; 
whole_text.Split(delimiters,StringSplitOptions.RemoveEmptyEntries).Length; 
+2

To byłaby "część z nich jest lepsza", o której wspomniałem w mojej odpowiedzi;) +1. –

+0

+1 dla 'RemoveEmptyEntries'. Ma to znaczenie, jeśli w wierszu znajduje się wiele białych znaków. – Groo

2

To była projekcja telefon wywiad wątpliwości, że po prostu wziął (o dużej firmy znajduje się w CA, który sprzedaje wszystkie rodzaje urządzeń, które rozpoczyna się literą „I”), i myślę, że opodatkowane ... po tym, jak zostałem zalogowany, napisałem to. Chciałbym móc to zrobić podczas wywiadu ..

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

Użyliśmy dostosowaną formę odpowiedzi Yoshi, gdzie my Naprawiono błąd, gdzie nie liczyłbym ostatnie słowo w ciąg, jeśli nie było white-space po nim:

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

Proszę podać wyjaśnienie kodu w swojej odpowiedzi. –

-1

Możesz także zrobić to w ten sposób! Dodaj tę metodę do swoich metod rozszerzenia.

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

I nazwij to tak.

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

daje to złą odpowiedź, jeśli mamy wiele spacji lub "\ r \ n" pomiędzy słowami. – Artemious

0

To powinno działać

input.Split(' ').ToList().Count; 
Powiązane problemy