从排序的数字列表生成正则表达式数字范围

时间:2013-11-15 20:39:16

标签: regex algorithm range digit

假设我有一些整数排序列表,我想将它们转换为各自的正则表达式数字范围,如下所示:

  1. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] => [0-9]
  2. [0, 1, 2, 3, 4, 6, 7, 8, 9] => [0-46-9]
  3. [0, 1, 3, 4, 5, 8, 9] => [013-589]
  4. [0, 2, 4, 6, 8] => [02468]
  5. 我不是想在这里匹配任何正则表达式。我正在尝试从一组数字生成正则表达式范围

    我真的只是想看看是否已经有一些事实上的算法来做这样的事情。

    编辑:基于@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]

    随意找到改进或问题。

2 个答案:

答案 0 :(得分:3)

据推测,你是从排序输入开始的(如果没有,你几乎肯定想从排序输入开始)。

从那里开始,从第一个(未处理的)项目开始,写出来。只要它们是连续的,就可以浏览数字。假设您连续两次以上,请写出破折号,然后是最后一个连续数字。如果您有两个或更少的连续,只需按原样将它们写入输出。

重复,直到到达输入的末尾。

答案 1 :(得分:0)

我可以提出一种不同的方法。

遍历列表识别间隔。我们保留两个变量leftright(区间界限),每次我们有两个连续值时,我们将间隔写为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);
}