2016-01-29 75 views
4

在C#中的數組,因爲數組:發生的最大數目的字符出現在字符串

string[] myStrings = new string[] { 
    "test#test", 
    "##test", 
    "######", // Winner (outputs 6) 
}; 

我如何才能找到事件的最大數目的字符#出現在一個字符串?

我目前的解決辦法是:

int maxOccurrences = 0; 
foreach (var myString in myStrings) 
{ 
    var occurrences = myString.Count(x => x == '#'); 
    if (occurrences > maxOccurrences) 
    { 
     maxOccurrences = occurrences; 
    } 
} 

return maxOccurrences; 

是他們使用LINQ可以直接在myStrings[]陣列行事的simplier方式?

這可以做成擴展方法,可以在任何IEnumerable<string>工作?

回答

8

首先,讓我們伸出你的字符串與匹配的計數序列:

myStrings.Select(x => x.Count(x => x == '#')) // {1, 2, 6} in your example 

然後拿起最大值:

int maximum = myStrings 
    .Select(s => s.Count(x => x == '#')) 
    .Max(); // 6 in your example 

讓我們做一個擴展方法:

public static int CountMaximumOccurrencesOf(this IEnumerable<string> strings, char ch) 
{ 
    return strings 
     .Select(s => s.Count(c => c == ch)) 
     .Max(); 
} 

但是有一個大的但是。你在C#中調用char不是你所說的語言中的字符。這已在其他帖子中被廣泛討論,例如:Fastest way to split a huge text into smaller chunksHow can I perform a Unicode aware character by character comparison?,那麼我不會在這裏重複一切。要「統一認識」你需要讓你的代碼更加複雜(請注意代碼寫到這裏那麼它是未經測試):

private static IEnumerable<string> EnumerateCharacters(string s) 
{ 
    var enumerator = StringInfo.GetTextElementEnumerator(s.Normalize()); 
    while (enumerator.MoveNext()) 
     yield return (string)enumerator.Value; 
} 

我們原來的代碼然後更改爲:

public static int CountMaximumOccurrencesOf(this IEnumerable<string> strings, string character) 
{ 
    return strings 
     .Select(s => s.EnumerateCharacters().Count(c => String.Equals(c, character, StringComparison.CurrentCulture)) 
     .Max(); 
} 

注意Max()單獨要求收集不能爲空(如果收集可能爲空並且不是錯誤,則使用DefaultIfEmpty())。要做到不隨意決定如何在這種情況下做的(拋出一個異常,如果它要發生或只返回0),你可以可以使這種方法不太專業的,離開這個責任來電者:

public static int CountOccurrencesOf(this IEnumerable<string> strings, 
    string character, 
    StringComparison comparison = StringComparison.CurrentCulture) 
{ 
    Debug.Assert(character.EnumerateCharacters().Count() == 1); 

    return strings 
     .Select(s => s.EnumerateCharacters().Count(c => String.Equals(c, character, comparison)); 
} 

像這樣來使用:

var maximum = myStrings.CountOccurrencesOf("#").Max(); 

如果你需要它不區分大小寫:

var maximum = myStrings.CountOccurrencesOf("à", StringComparison.CurrentCultureIgnoreCase) 
    .Max(); 

正如你現在能想象這種比較並不侷限於某些深奧語言,但它也適用於不變文化(en-US),那麼對於必須始終與不變文化進行比較的字符串,您應指定StringComparison.InvariantCulture。不要忘記,您也可能需要撥打String.Normalize()來輸入字符。

+0

呸,只是打我給它。 – krillgar

1

你可以寫這樣的東西。請注意0​​的使用情況,如果myStrings爲空則不會拋出異常,但會恢復爲0

var maximum = myStrings.Select(e => e.Count(ee => ee == '#')).DefaultIfEmpty().Max(); 
0

你可以做到這一點與Linq結合,Regex

myStrings.Select(x => Regex.Matches(x, "#").Count).max(); 
相關問題