[英]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)
這與正則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.