2011-02-05 3 views
1

사용자가 입력 할 특정 단어에 대한 문자열을 검색 한 다음 해당 단어가 텍스트 내에 표시되는 백분율을 출력하고 싶습니다. 이걸위한 최선의 방법이 무엇이 될지 궁금해하고 저를 도울 수 있다면 제발.특정 Word의 문자열을 검색 중입니다. C#

+0

정확히 말해서 백분율로 무엇을 의미합니까? –

+1

나는 그가 얼마나 많은 (number_of_times_word_to_find_occurs/total_number_of_words) * 100을 의미한다고 가정하고있다. – david

답변

0

내 제안은 완전한 수업입니다.

class WordCount { 
    const string Symbols = ",;.:-()\t!¡¿?\"[]{}&<>+-*/=#'"; 

    public static string normalize(string str) 
    { 
     var toret = new StringBuilder(); 

     for(int i = 0; i < str.Length; ++i) { 
      if (Symbols.IndexOf(str[ i ]) > -1) { 
       toret.Append(' '); 
      } else { 
       toret.Append(char.ToLower(str[ i ])); 
      } 
     } 

     return toret.ToString(); 
    } 

    private string word; 
    public string Word { 
     get { return this.word; } 
     set { this.word = value; } 
    } 

    private string str; 
    public string Str { 
     get { return this.str; } 
    } 

    private string[] words = null; 
    public string[] Words { 
     if (this.words == null) { 
      this.words = this.Str.split(' '); 
     } 

     return this.words; 
    } 

    public WordCount(string str, string w) 
    { 
     this.str = ' ' + normalize(str) + ' '; 
     this.word = w; 
    } 

    public int Times() 
    { 
     return this.Times(this.Word); 
    } 

    public int Times(string word) 
    { 
     int times = 0; 

     word = ' ' + word + ' '; 

     int wordLength = word.Length; 
     int pos = this.Str.IndexOf(word); 

     while(pos > -1) { 
      ++times; 

      pos = this.Str.IndexOf(pos + wordLength, word); 
     } 

     return times; 
    } 

    public double Percentage() 
    { 
     return this.Percentage(this.Word); 
    } 

    public double Percentage(string word) 
    { 
     return (this.Times(word)/this.Words.Length); 
    } 
} 

장점 : 문자열 분할이 캐시되므로 두 번 이상 적용 할 위험이 없습니다. 하나의 클래스에 패키지되어 있기 때문에 쉽게 재 작성할 수 있습니다. Linq의 필요성 없음. 희망이 도움이됩니다.

2

가장 쉬운 방법은 LINQ를 사용하는 것입니다 :

char[] separators = new char() {' ', ',', '.', '?', '!', ':', ';'}; 
var count = 
    (from word In sentence.Split(separators)  // get all the words 
    where word.ToLower() = searchedWord.ToLower() // find the words that match 
    select word).Count();       // count them 

이 만 단어가 텍스트로 표시 횟수를 계산합니다. 나는 더 나은 성능을 위해 지정된 StringComparisonString.Equals 오버로드를 사용하는 것이 좋습니다

var result = count/totalWords * 100; 
+3

이렇게 많은 코너 케이스가 있습니다. "one, two, three"문장에서 "two"를 검색하면 분할이 요소 "2"(쉼표 포함)를 제공하므로 일치하는 항목이 없습니다. 즉, 사용자가 모든 구분 기호를 고려하여 분리하기 전에 분리자를 제거해야합니다 (즉, 사용자가 분리자를 검색하지 않는 한). –

+1

@Fredrik 네 말이 맞아. 가능한 모든 구분 기호를 찾는 것이 약간 어렵다. 몇 가지 사례를 더 잡으려고 편집했습니다. – alex

+0

코드를 복사하는 경우 두 개의 'Split' 호출이 있습니다. –

3

: 그냥 비율을 얻을 다음

var totalWords = sentence.Split(separators).Count()); 

과 : 당신은 또한 텍스트에 얼마나 많은 단어를 셀 수 있습니다.

var separators = new [] { ' ', ',', '.', '?', '!', ';', ':', '\"' }; 
var words = sentence.Split (separators); 
var matches = words.Count (w => 
    w.Equals (searchedWord, StringComparison.OrdinalIgnoreCase)); 
var percentage = matches/(float) words.Count; 

참고 percentagefloat 예컨대 것이라고 0.5 50 %. 이 방법은 큰 문자열 때문에에 효과가 있음을

var formatted = percentage.ToString ("P2"); // 0.1234 => 12.34 % 

명심하십시오 :

var formatted = percentage.ToString ("P0"); // 0.1234 => 12 % 

당신은 또한 소수점 이하 자릿수를 표시하는 형식 지정을 변경할 수 있습니다
당신은 ToString 오버로드를 사용하여 표시를 포맷 할 수 있습니다 발견 된 단어 각각에 대한 문자열 인스턴스를 작성합니다. StringReader을 사용하고 단어 단위로 단어를 읽으세요.

+2

이것은 가장 많은 구분자를 찾을 수있는 경주로 변하고 있습니다. :) – alex

+0

@alex : 하하, 당신도 그렇게 생각하지 않았다 :-) –

0
// The words you want to search for 
var words = new string[] { "this", "is" }; 

// Build a regular expresion query 
var wordRegexQuery = new System.Text.StringBuilder(); 
wordRegexQuery.Append("\\b("); 
for (var wordIndex = 0; wordIndex < words.Length; wordIndex++) 
{ 
    wordRegexQuery.Append(words[wordIndex]); 
    if (wordIndex < words.Length - 1) 
    { 
    wordRegexQuery.Append('|'); 
    } 
} 
wordRegexQuery.Append(")\\b"); 

// Find matches and return them as a string[] 
var regex = new System.Text.RegularExpressions.Regex(wordRegexQuery.ToString(), RegexOptions.IgnoreCase); 
var someText = var someText = "This is some text which is quite a good test of which word is used most often. Thisis isthis athisisa."; 
var matches = (from Match m in regex.Matches(someText) select m.Value).ToArray(); 

// Display results 
foreach (var word in words) 
{ 
    var wordCount = (int)matches.Count(w => w.Equals(word, StringComparison.InvariantCultureIgnoreCase)); 
    Console.WriteLine("{0}: {1} ({2:f2}%)", word, wordCount, wordCount * 100f/matches.Length); 
} 
관련 문제