重复字符的字符串压缩
本文关键字:字符串 压缩 字符 | 更新日期: 2023-09-27 18:32:34
我有以下两个字符串。
uncompressed "(A(2),I(10),A,A,A,A(3),R,R,R,R,A,A)"
compressed "(A(2),I(10),3A,A(3),4R,2A)"
忽略 A(n) 或 I(n) 格式的任何条目,您可以看到,当我们找到任何连续重复的字符时,它会替换为该位置的单个条目和一个计数。
我知道一定有一种优雅的方法可以做到这一点,但我不断想出看起来很丑的嵌套循环。
字符串中的数据来自ISO8211文件格式,并标识要应用于子字段中数据的格式。
我相信这可以用一行 linq 来完成,但我没有想法(今晚)。
该技术称为运行长度编码。
下面是一个使用 Python 的示例:
from itertools import groupby
uncompressed = "(A(2),I(10),A,A,A,A(3),R,R,R,R,A,A)"
counted = [(k, len(list(g))) for k, g in groupby(uncompressed.split(','))]
compressed = ','.join(k if cnt==1 else str(cnt)+k for k, cnt in counted)
嗯,不完全是一行。这将做到这一点:
string str = "(A(2),I(10),A,A,A,A(3),R,R,R,R,A,A)";
string prev = null;
int cnt = 0;
string result =
"(" + String.Join(",",
(str.TrimStart('(').TrimEnd(')') + ",").Split(',').Select(x => {
if (x == prev) {
cnt++;
return null;
} else {
string temp = cnt > 1 ? cnt.ToString() + prev : prev;
prev = x;
cnt = 1;
return temp;
}
}).Where(x => x != null)
) + ")";
下面是一个使用 LINQ GroupBy
的方法
static string RLE(string s) {
s = s.Substring(1, s.Length - 2);
char? l = null;
int i = 0;
return "(" + string.Join(",", s.Split(',').GroupBy(c => {
if(c.Length != 1) {
i++;
return i++;
}
if(c[0] == l) {
return i;
}
l = c[0];
return ++i;
}).Select(x => (x.Count() > 1 ? x.Count().ToString() : string.Empty) + x.First())) + ")";
}