簡體   English   中英

優化字符串中的計數字符

[英]Optimizing counting characters within a string

我剛剛創建了一個簡單的方法來計算字符串中每個字符的出現次數,而不考慮上限。

static List<int> charactercount(string input)
        {
            char[] characters = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
            input = input.ToLower();

            List<int> counts = new List<int>();
            foreach (char c in characters)
            {
                int count = 0;
                foreach (char c2 in input) if (c2 == c)
                    {
                        count++;
                    }

                counts.Add(count);
             }

            return counts;

        }

有沒有更簡潔的方法來做到這一點(即沒有創建一個字符數組來保存字母表中的每個字符),這也會考慮數字,其他字符,大寫等?

從概念上講,我更願意返回計數的Dictionary<string,int> 我假設可以通過省略而不是顯式計數0知道一個字符出現零次,你可以通過LINQ來做。 @Oded給你一個良好的開端,如何做到這一點。 您需要做的就是用ToDictionary( k => k.Key, v => v.Count() )替換Select() ToDictionary( k => k.Key, v => v.Count() ) 請參閱我對他關於進行不區分大小寫分組的回答的評論。 注意:您應該決定是否關心字符的文化差異,並相應地調整ToLower方法。

你也可以不用LINQ做到這一點;

public static Dictionary<string,int> CountCharacters(string input)
{
     var counts = new Dictionary<char,int>(StringComparer.OrdinalIgnoreCase);

     foreach (var c in input)
     {
          int count = 0;
          if (counts.ContainsKey(c))
          {
              count = counts[c];
          }
          counts[c] = counts + 1;
     }

     return counts;
}

注意,如果你想要一個Dictionary<char,int> ,你可以通過創建一個case不變字符比較器並將其作為IEqualityComparer<T>用於所需類型的字典來輕松完成。 我在示例中使用了string來簡化。

同樣,調整比較器的類型以與您希望處理文化的方式一致。

使用GroupBySelect

aString.GroupBy(c => c).Select(g => new { Character = g.Key, Num = g.Count() })

返回的匿名類型列表將包含每個字符及其在字符串中出現的次數。

然后,您可以使用Char定義的靜態方法以任何方式過濾它。

您的代碼有點慢,因為您循環遍歷范圍az而不是僅僅循環輸入。

如果您只需要計算字母(如代碼所示),最快的方法是:

int[] CountCharacters(string text)
{
    var counts = new int[26];

    for (var i = 0; i < text.Length; i++)
    {
        var charIndex - text[index] - (int)'a';
        counts[charIndex] = counts[charindex] + 1;
    }

    return counts;
}  

請注意,您需要添加一些內容,例如驗證字符是否在范圍內,並在需要時將其轉換為小寫,否則此代碼可能會拋出異常。 我會留下那些給你補充的。 :)

基於+ Ran的回答來避免IndexOutOfRangeException

static readonly int differ = 'a';
int[] CountCharacters(string text) {
    text = text.ToLower();
    var counts = new int[26];

    for (var i = 0; i < text.Length; i++) {
        var charIndex = text[i] - differ;
        // to counting chars between 'a' and 'z' we have to do this:
        if(charIndex >= 0 && charIndex < 26)
            counts[charIndex] += 1;
    }
    return counts;
}

實際上使用Dictionary和/或LINQ並不足以優化計數字符和使用低級數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM