2013-11-15 87 views
1

假設我有一個整數的一些排序名單,我想將它們轉換爲各自的正則表達式的數字範圍,像這樣:生成正則表達式的數字範圍

  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]

我並不想雷傑x匹配任何東西。我試圖從產生一個正則表達式範圍一組數字。

我真的只是想看看是否已經有一些事實上的算法來做這樣的事情。

編輯:基於@ 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

而這些列表已經排序? –

+0

是的,他們被排序。將更新問題以明確說明。 –

回答

3

假設你從排序後的輸入開始(如果不是,你幾乎肯定希望從排序輸入開始)。

從那裏,從第一個(未處理)項目開始,寫出來。只要連續數字,就可以遍歷數字。假設你連續超過兩次,寫出一個短劃線,然後寫出最後一個連續的數字。如果連續兩次或更少,只需將它們按原樣輸出即可。

重複,直到您到達輸入的末尾。

+0

根據#3 - 「假設您獲得超過**兩個**連續」。 – Dukeling

+0

@Dukeling:好點。 –

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); 
}