簡體   English   中英

計算類似於游程編碼c#的字符串中的出現次數

[英]count occurrences in a string similar to run length encoding c#

說我有一個像

MyString1 = "ABABABABAB";
MyString2 = "ABCDABCDABCD";
MyString3 = "ABCAABCAABCAABCA";
MyString4 = "ABABACAC";
MyString5 = "AAAAABBBBB";

我需要得到以下輸出

Output1 = "5(AB)";
Output2 = "3(ABCD)";
Output3 = "4(ABCA)";
Output4 = "2(AB)2(AC)";
Output5 = "5(A)5(B)";

我一直在研究RLE,但我不知道該怎么做。 我一直在使用的代碼是

public static string Encode(string input)
{
    return Regex.Replace(input, @"(.)\1*", delegate(Match m)
    {
        return string.Concat(m.Value.Length, "(", m.Groups[1].Value, ")");
    });
}

這適用於Output5,但是我可以使用Regex做其他輸出嗎?還是應該使用類似Linq的東西?

該代碼的目的是以一種簡單的方式顯示MyString,因為我通常可以將MyString最多包含1000個字符並帶有一個模式。
我不太擔心速度。

將RLE與單個字符一起使用很容易,匹配之間絕不會重疊。 如果要重復的字符數是可變的,則可能會出現問題:

AAABAB

可能:

3(A)BAB

要么

AA(2)AB

您必須定義要應用的規則。 您是否想要絕對最佳的壓縮? 速度重要嗎?

我懷疑Regex是否可以期待並選擇“最佳”匹配項-因此,要回答您的問題,我會說“否”。

RLE在這里沒有幫助-它只是一個非常簡單的壓縮,在此壓縮中,您重復單個代碼點給定次數。 這對於例如游戲圖形和透明圖像(“下一個,有50個透明像素”)非常有用,但是對於可變長度的代碼點將無濟於事。

相反,請看霍夫曼編碼。 擴展它以與可變長度碼字一起使用並不便宜,但這只是一個開始-如果您可以負擔得起那里的桌子,它可以節省很多空間。

但是,您首先要問自己的是,您要優化什么? 您是否要在輸出中獲取最短的字符串? 您要追求速度嗎? 您是否需要盡可能少的代碼字,還是需要以某種方式平衡重復次數和代碼字數? 換句話說,您實際上想做什么? :))

為了說明您的“期望”返回值,Output4產生的字符串比MyString4長。 因此,這不是最短的表示形式。 您也不會嘗試最少的代碼字,因為那樣Output5將是1(AAAAABBBBB) 重復的次數最少當然很愚蠢(它總是1(...) )。 您也沒有針對低開銷進行優化,因為這在Output4中再次被破壞。

無論您要嘗試使用哪種方法,我都想使用正則表達式是不可能的-正則表達式僅適用於正則語言,而這樣的編碼對我來說似乎並不是那么正則。 解碼當然可以; 但我不太確定編碼。

給定您提供的數據,這是一種非Regex方式。 我不確定目前是否有任何極端情況會破壞此代碼。 如果是這樣,我將進行相應的更新。

string myString1 = "ABABABABAB";
string myString2 = "ABCDABCDABCD";
string myString3 = "ABCAABCAABCAABCA";
string myString4 = "ABABACAC";
string myString5 = "AAAAABBBBB";

CountGroupOccurrences(myString1, "AB");
CountGroupOccurrences(myString2, "ABCD");
CountGroupOccurrences(myString3, "ABCA");
CountGroupOccurrences(myString4, "AB", "AC");
CountGroupOccurrences(myString5, "A", "B");

CountGroupOccurrences()如下所示:

private static void CountGroupOccurrences(string str, params string[] patterns)
{
    string result = string.Empty;
    while (str.Length > 0)
    {
        foreach (string pattern in patterns)
        {
            int count = 0;
            int index = str.IndexOf(pattern); 
            while (index > -1)
            {
                count++;
                str = str.Remove(index, pattern.Length);
                index = str.IndexOf(pattern); 
            }
            result += string.Format("{0}({1})", count, pattern);
        }
    }
    Console.WriteLine(result);
}

結果:

5(AB)
3(ABCD)
4(ABCA)
2(AB)2(AC)
5(A)5(B)

UPDATE

這與正則Regex一起工作

private static void CountGroupOccurrences(string str, params string[] patterns)
{
    string result = string.Empty;
    foreach (string pattern in patterns)
    {
        result += string.Format("{0}({1})", Regex.Matches(str, pattern).Count, pattern);
    }
    Console.WriteLine(result);
}

暫無
暫無

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

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