假设您有一个包含服务器名称的已排序列表。您希望尽可能紧凑地折叠它们。
例如:
什么是处理此类问题的最简单算法?
例如:
abcd01c, abcd02c, abcd04c, abcd05, z1x
应该变成
abcd0[1-4]c,abcd05,z1x
什么是处理此类问题的最简单算法?
(0)abcd01c
(5) 2c,
(5) 4c,
(4) 05,
(0)z1x
Trie
来实现这个功能...我认为您可以在此处使用它来存储所有内容,只需要一个自定义遍历函数以按所需格式获取数据即可。 - Brian Roach我认为动态规划可以帮助解决问题。可以计算给定数组所有第一个元素的集合的最短长度,例如 {1},{1,2},{1,2,3}... 这些数字是连续计算的,因此需要使用先前的数字来计算当前数字。如果我们想要计算 A[i],并且已知 A[j](其中 j < i),并且从 j+1 到 i 的给定数组中的数字可以被压缩,则 A[i] 等于 A[j] + 压缩数据的长度。
更新
如果范围设置为多个符号,我几乎不理解如何进行压缩。因此,在这里提供了一种简单的实现方式,适用于一个符号的情况。
int prevIdx = -1;
int count = 0;
for (int i = 1; i < list.Length; i++) {
bool ok = true;
if (list[i].Length == list[i - 1].Length) {
int count = 0;
for (int j = 0; j < list[i].Length; j++)
if (list[i][j] != list[i - 1][j])
curIdx = j;
count++;
}
if (count > 1)
ok = false;
}
else
ok = false;
if (ok) {
if (prevIdx == curIdx) {
count++;
}
else {
prevIdx = curIdx;
if (count > 1)
answer.Add(list[i - 1].SubString(0, prevIdx - 1) +
'[' + count.ToString() + ']' + list[i - 1].SubString(prevIdx + 1, list[i - 1].Length);
else
answer.Add(list[i - 1]);
count = 0;
}
}
else {
if (count > 1)
answer.Add(list[i - 1].SubString(0, prevIdx - 1) +
'[' + count.ToString() + ']' + list[i - 1].SubString(prevIdx + 1, list[i - 1].Length);
else
answer.Add(list[i - 1]);
prevIdx = -1;
}
}
if (count > 1)
answer.Add(list[List.Length - 1].SubString(0, prevIdx - 1) +
'[' + count.ToString() + ']' + list[i - 1].SubString(prevIdx + 1, list[List.Length - 1].Length);
else
answer.Add(list[list.Length - 1]);
我对您的实际需求有些摸不着头脑,但是一种解决方法是使用自定义Trie(维基百科条目)。
当您到达键中下一个字符不是字母字符的点时,您将知道您有一个前缀。在Trie中的该节点内,您可以再次拥有另一个映射(不指向其他Trie节点),其由后缀键入并包含每个范围。
然而,您仍然面临特定数据规则的问题。如果您的键为abcd01c
,那么前缀是abcd
还是abcd0
?
abcd0[1-4]c
代替特殊的包装对象? - Eric