2012-01-09 71 views
9

Tôi đang cố đếm số từ từ hộp văn bản có định dạng trong C# mã mà tôi có dưới đây chỉ hoạt động nếu nó là một dòng. Làm thế nào để làm điều này mà không dựa vào regex hoặc bất kỳ chức năng đặc biệt khác.Đếm số từ trong 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

Dưới đây là một gợi ý cho bài tập về nhà: nhìn vào [dòng] (http://msdn.microsoft.com/en-us/library/system.windows. forms.textboxbase.lines.aspx) thuộc tính của RichTextBox để truy xuất nội dung của RTB. –

Trả lời

15

Vì bạn chỉ quan tâm đến từ đếm, và bạn không quan tâm đến lời nói cá nhân, String.Split có thể tránh được. String.Split là tiện dụng, nhưng nó không nhất thiết tạo ra một số lượng (có thể) số lượng lớn các đối tượng String, do đó tạo ra một gánh nặng không cần thiết trên bộ thu gom rác. Đối với mỗi từ trong văn bản của bạn, một đối tượng String mới cần được khởi tạo và sau đó sẽ sớm được thu thập vì bạn không sử dụng nó. Đối với một bài tập về nhà, điều này có thể không quan trọng, nhưng nếu nội dung hộp văn bản của bạn thay đổi thường xuyên và bạn thực hiện phép tính này bên trong một trình xử lý sự kiện, có thể khôn ngoan hơn khi chỉ lặp lại các ký tự theo cách thủ công. Nếu bạn thực sự muốn sử dụng String.Split, thì hãy sử dụng phiên bản đơn giản hơn như được khuyến nghị là Yonix.

Nếu không, sử dụng một thuật toán tương tự như sau:

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

Mã này nên làm việc tốt hơn với trường hợp bạn có nhiều khoảng trống giữa mỗi từ.

0

Cách tiếp cận của bạn là đi đúng hướng. Tôi sẽ làm một cái gì đó như, đi qua các tài sản văn bản của richTextBox1 vào phương pháp. tuy nhiên điều này sẽ không chính xác nếu textbox giàu của bạn được định dạng HTML, vì vậy bạn sẽ cần phải loại bỏ bất kỳ thẻ HTML trước khi chạy từ đếm:

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

Có một cái nhìn tại Lines tài sản nêu tại @ Jay Riggs bình luận, cùng với this overload of String.Split để làm cho mã đơn giản hơn nhiều. Sau đó, cách tiếp cận đơn giản nhất là lặp qua mỗi dòng trong thuộc tính Lines, gọi String.Split trên đó và thêm độ dài của mảng mà nó trả về số lần chạy.

EDIT: Ngoài ra, có bất kỳ lý do nào bạn đang sử dụng RichTextBox thay vì một TextBox với Multiline được đặt thành True không?

4

Có một số cách tốt hơn để làm điều này, nhưng phù hợp với những gì bạn đã có, hãy thử như sau:

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

Bây giờ làm cho hai vòng foreach. Một cho mỗi dòng và một cho đếm từ trong dòng.

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

Điều này sẽ là "có những cách tốt hơn để làm điều này" một phần mà tôi đã đề cập trong câu trả lời của tôi;) 1. –

+0

+1 cho 'RemoveEmptyEntries'. Nó tạo sự khác biệt nếu có nhiều ký tự khoảng trắng trong một hàng. – Groo

2

Đây là một câu hỏi phỏng vấn sàng lọc điện thoại mà tôi chỉ mất (do một công ty lớn nằm ở CA người bán tất cả các loại thiết bị bắt đầu với một chữ "i"), và tôi nghĩ rằng tôi franked ... sau khi tôi ngoại tuyến, tôi đã viết điều này. Tôi ước tôi có thể làm điều đó trong khi phỏng vấn ..

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

Chúng tôi đã sử dụng một hình thức thích nghi của câu trả lời của Yoshi, nơi chúng tôi sửa lỗi nơi nó sẽ không được tính từ cuối cùng trong một chuỗi nếu không có màu trắng-không gian sau nó:

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

Vui lòng cung cấp một số giải thích cho mã trong câu trả lời của bạn. –

-1

Bạn cũng có thể làm theo cách này !! Thêm phương thức này vào các phương thức mở rộng của bạn.

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

Và gọi nó như thế này.

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

điều này trả lời sai nếu chúng ta có nhiều dấu cách hoặc dấu ngắt dòng "\ r \ n" giữa các từ. – Artemious

0

này nên làm việc

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