假设我有一些整数排序列表,我想将它们转换为各自的正则表达式数字范围,如下所示:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] => [0-9]
[0, 1, 2, 3, 4, 6, 7, 8, 9] => [0-46-9]
[0, 1, 3, 4, 5, 8, 9] => [013-589]
[0, 2, 4, 6, 8] => [02468]
我不是想在这里匹配任何正则表达式。我正在尝试从一组数字生成正则表达式范围。
我真的只是想看看是否已经有一些事实上的算法来做这样的事情。
编辑:基于@Jerry_Coffin的答案,基于Java的算法:
List<Integer> digits = Arrays.asList(0, 1, 3, 4, 5, 8, 9);
StringBuilder digitRange = new StringBuilder().append('[');
int consecutive = 0;
for (int i = 0; i < digits.size(); i++) {
if (i == digits.size() - 1 || digits.get(i) + 1 != digits.get(i + 1)) {
if (consecutive > 1) {
digitRange.append('-');
}
digitRange.append(digits.get(i));
consecutive = 0;
} else {
if (consecutive == 0) {
digitRange.append(digits.get(i));
}
consecutive++;
}
}
digitRange.append(']');
System.out.println(digitRange.toString());
输出:[013-589]
随意找到改进或问题。
答案 0 :(得分:3)
据推测,你是从排序输入开始的(如果没有,你几乎肯定想从排序输入开始)。
从那里开始,从第一个(未处理的)项目开始,写出来。只要它们是连续的,就可以浏览数字。假设您连续两次以上,请写出破折号,然后是最后一个连续数字。如果您有两个或更少的连续,只需按原样将它们写入输出。
重复,直到到达输入的末尾。
答案 1 :(得分:0)
我可以提出一种不同的方法。
遍历列表识别间隔。我们保留两个变量left
和right
(区间界限),每次我们有两个不连续值时,我们将间隔写为StringBuilder
。
int[] list = new[] { 0, 1, 3, 4, 5, 8, 9 };
int left = 0;
int right = 0;
for (int i = 0; i < list.Length; i++)
{
if (i == 0) // first case
{
left = right = list[i];
continue;
}
if (list[i] - list[i - 1] > 1) // not consecutive
{
builder.AppendFormat(Write(left, right));
left = list[i];
}
right = list[i];
}
builder.AppendFormat(Write(left, right));// last case
builder.Append("]");
写方法:
private static string Write(int left, int right)
{
return
left == right
? left.ToString()
: right - left == 1
? string.Format("{0}{1}", left, right)
: string.Format("{0}-{1}", left, right);
}