2016-11-20 41 views
1

需要查找包含條件的文本片段:需要從文本中查找最長的文本片段,其中的單詞以與前一個單詞的最後一個字母相同的字母開頭(例如:1. my 2年)。我需要打印出該片段以及他在文本中的行號。我的代碼:C#在文本中找不到正確的片段

public static string Longestfragment(string[] lines,char[] isolations ,ref int index) 
{ 
    string longestSentense = ""; 
    int longestCount = 0; 
    int start = 0; 
    int end = 0; 

    foreach (string sentense in lines) 
    { 
     string[] words = sentense.Split(isolations); // split the words 
     int count = 0; 
     int line = 0; 
     line++; 
     for (int i = 0; i < words.Length - 1; i++) 
     { 
      // checking if the first word ends equals to the second word start 
      if (words[i].Equals("") || words[i + 1].Equals("")) continue; // checking if one of the words not empty. 
      if (words[i][words[i].Length - 1].Equals(words[i + 1][0])) 
      { 
       if (count == 0) //to find the start of fragment 
       { 
        start = sentense.IndexOf(words[i][0]); 
        end = sentense.IndexOf(words[i + 1][words[i + 1].Length - 1]); 
       }// to find the end of the fragment if the fragment if longer than 2 words. 
       if (count >= 1) 
       { 
        end = sentense.IndexOf(words[i + 1][words[i + 1].Length - 1]); 
       } 
       count++; 

      } 

     } 
     // if there is the longest fragment we save it. 
     if (count > longestCount) 
     { 
      longestCount = count; 
      longestSentense = sentense.Substring(start,end-1); 
      index = line; // to find the line index 
     } 
    } 
    return longestSentense; //returning the value of longestfragment 
} 

如果我的文本文件是:

大家好,我是山姆。我的歲月如此美好。

我得到的指數1(我想應該是0)和最長的句子(是薩姆。我多年的那麼好。)這是正確的。但是如果我的文本文件包含2行或更多行,如:

等於序列輸入繩八。

嗨,我叫薩姆。我的歲月如此美好。

我的程序只是崩潰或打印出錯誤的句子。請幫忙。

+0

你能準確定義片段應該開始和結束的位置嗎?它是從第一次出現相同字母結尾和開頭的兩個單詞開始的嗎?它在哪裏結束?在行結尾?在下一個點'.'?那麼'你好,我叫薩姆。我的歲月如此美好。從來沒有更好。「這個片段在哪裏結束? –

+0

@MongZhu它開始時,這兩個詞包含我說的條件。並在一個字母和另一個字母以不同的字母開頭時結束。 – Julius

+0

因爲你在循環之前增加了'line',所以你得到index = 1。你如何處理標點符號? 'char [] isolation'的內容是什麼? –

回答

1

我不知道這是否是一個選項,但搜索文本的模式可以通過正則表達式比通過循環更有效和容易地完成。

我很快就砍死一個共同爲您將發現所有的圖案文字:example regex screenshot

\w+(\w)\s\g{-1}\w+ 

您可以將所有的比賽導出到例如一個列表,然後搜索這個列表中最長的一個。

雖然正則表達式可能非常棘手,有時也是不可預測的,但請注意。我最有可能wwill不會失敗,也不考慮像aword,danotherword這樣的事情,因爲它不包括標點符號等。 但是這應該提供一個好方向的提示。

編輯: .NET directly supports regexes。它在命名空間:

System.Text.RegularExpressions 
0

你的主要問題是這一行:

end = sentense.IndexOf(words[i + 1][words[i + 1].Length - 1]); 

我相信它會搜索從符合您的條件的第二個字的最後一個字母的指數。

在這個句子:

等於序列進入繩八。

i == 4到達的話eightthe。如果您的the =>eIndexOf()返回的最後一個字母的指數,以你現在搜索:

在數組值中第一次出現的索引,

所以,你得到0因爲你句子e開始,你用完了這行界,當你嘗試-1位置來訪問一個元素:

longestSentense = sentense.Substring(start, end - 1); 

解決方案:

  • 我建議來計算使用整個字,並且該方法LastIndexOf()最終索引。它將返回33的單詞the,因爲它從這一點開始。您只需要添加單詞的長度,並且您已結束:

    end = sentense.LastIndexOf(words [i + 1])+ words [i + 1] .Length;

  • 當您從句子中訪問Substring()時。第二個參數是length而不是結束。

公共字符串的子串(INT的startIndex,INT長度)

所以,你會需要減去開始索引:

longestSentense = sentense.Substring(start, end-start); 
  • 開始索引也被冒充像結束一樣的問題。第一次出現! 我也建議搜索這個詞,而不是字母。舉例如下這句話:

嗨,我叫喬。我的歲月如此美好。後Joe.myIndexOf(String s)將返回第一my

您的片段將開始。您應該計算偏移量,你繼續向上計數,當您去通過每一個單詞在句子:

if (Char.ToLower(words[i].Last()) == char.ToLower(words[i + 1].First())) 
{ 
    offset += words[i].Length; 

    if (count == 0) //to find the start of fragment 
    { 
     start = sentense.IndexOf(words[i], offset); 
     end = sentense.LastIndexOf(words[i + 1]) + words[i + 1].Length; 
  • 而且不會第二if條件不採取大寫和小寫字母考慮這樣s == S會返回false。你可以迫使兩個字母是小寫來規避這樣的:

第2個if條件可以寫多一點可讀性:

// do only if neither `null` nor `empty` nor `space` 
if (!String.IsNullOrWhiteSpace(words[i] || !String.IsNullOrWhiteSpace(words[i+1]) 
{ // access the last and first elements using methods with such names 
    if (Char.ToLower(words[i].Last()) == char.ToLower(words[i + 1].First())) 
    { 

    } 
} 
  • 增量line在盡頭在最後的if條件之後的foreach循環。這會給你正確的路線。

  • 你應該要麼把Substring呼叫到try catch塊或檢查是否end可能是負,以避免異常:

    如果(計數> longestCount & &端> = 0) { longestCount =計數; longestSentense = sentense.Substring(start,end-start); index = line; //找到行索引 }

好吧,這是很多清理。玩得開心,我希望它有幫助。