2012-04-15 114 views
3

我有一個電話號碼範圍,例如:轉換電話號碼範圍列表前綴列表

3331234-3332345

我需要編寫它轉換爲前綴列表的功能:

3331234 
... 
3331239 
333124 
... 
333129 
33313 
... 
33319 
33320 
... 
33322 
333231 
333232 
333233 
3332341 
... 
3332345 

問題並不那麼容易。我不需要獲取範圍開始和結束之間的數字列表。

+3

您是否嘗試過_anything_自己嗎?我們不在這裏爲您編寫完整的解決方案。在其他新聞中,前綴究竟是什麼?我假設'333',但你的問題沒有指定。 – Bojangles 2012-04-15 20:10:50

+0

我不是在尋找代碼。我正在尋找dirction。前綴是包含完整10或100或1000等等的最長「字符串」。 – vpol 2012-04-15 20:14:56

回答

0

我的工作代碼。它不是很快,但工作。優化歡迎。

def fill(root, prefix, value, parent, pkey): 
    if len(prefix) > 1: 
     if prefix[0] in root: 
      fill(root[prefix[0]], prefix[1:], value, root, prefix[0]) 
      if pkey: 
       if len(parent[pkey]) == 10: 
        parent[pkey] = value 
     elif type(root) == type({}): 
      root[prefix[0]] = {} 
      fill(root[prefix[0]], prefix[1:], value, root, prefix[0]) 
      if pkey: 
       if len(parent[pkey]) == 10: 
        parent[pkey] = value 
    elif type(root) == type({}): 
     root[prefix[0]] = value 
     if pkey: 
      if len(parent[pkey]) == 10: 
       parent[pkey] = value 
    return root 

def compact(prefixes, current): 
    if not type(prefixes) == type({}): 
     return [current] 
    else: 
     rlist = [] 
     for k, v in prefixes.iteritems(): 
      rlist.extend(compact(v, current + k)) 
      continue 
     return rlist 

if __name__ == '__main__': 
    plist = {} 
    for x in range(4440000, 4490000): 
     fill(plist, str(x), 'value', plist, None) 
    #print plist 
    print compact(plist, '') 
0

你需要得到分隔值的公共前綴「 - 」,所以:

  • 使用.split得到這些和遍歷它們,直到找到一個差異
  • 完成與第一個值零(獲得數最少),直到你得到phone_len數字,做同樣的最大值(與九)
  • 然後,你必須通過他們的數字
  • 迭代的一個簡單的範圍,並將其轉換爲字符串

這就是:

phone_len = 7 
R = "33312345-3332345".split("-") 

prefix = "" 
for i in range(len(R[0])): 
    if R[0][i] == R[1][i]: 
     prefix += R[0][i] 
    else: 
     break 

m = int(R[0]+"0"*(phone_len-len(R[0]))) 
M = int(R[1]+"9"*(phone_len-len(R[0]))) 

phones = [str(n) for n in range(m, M+1)] 
+0

檢查我的前綴列表。有時它只有5位數,因此涵蓋全部100個數字,例如前綴33313 ... 33319覆蓋3331300和3331999之間的所有數字 – vpol 2012-04-15 20:23:31

+0

@vpol好的,對不起,您的問題不清楚......您能澄清一點嗎? – jadkik94 2012-04-15 20:32:36

+0

我編輯了這個問題。現在可以嗎? – vpol 2012-04-15 20:34:36

0

這裏的來處理這個問題的一種方式草圖。我用橢圓標記了需要填寫評論中解釋的細節的地方。我會寫一個函數來導出'maxpower'的初始值,其他所有內容都很簡單,可以直接寫入。

firstnumber = 3331234 
lastnumber = 3332345 

current = firstnumber 

while current <= lastnumber: 

    # Find the largest power of 10 that exactly divides 'current'. 
    # Call this value 'maxpower'. 'maxpower' is a candidate for the 
    # size of the block of numbers that will be represented by the 
    # next output value. 

    maxpower = ...  # 1, 10, 100, 1000, 10000, and so on 

    # If a block of size 'maxpower' would take us past the 
    # 'lastnumber', we can't use that block size. We must try a 
    # smaller block. Divide 'maxpower' by 10 until the block size 
    # becomes acceptable. 

    while (current + maxpower) > ... : 
     maxpower /= 10 

    # Now 'maxpower' is the largest acceptable size for the next 
    # block, so the desired prefix is 'current' divided by 'maxpower'. 
    # Emit that value, then add 'maxpower' to 'current' to get the new 
    # 'current' value for the next iteration. 

    print ... 
    current += maxpower 
1

我的工作代碼。它也不是很快。優化歡迎。

def diap_to_prefix(a, b): 
    lst = ['%0*d'%(max(len(str(a)), len(str(b))), x) for x in range(int(a), int(b)+1)] 
    new_lst = [] 

    while len(lst) != len(new_lst): 
     lst = new_lst or lst 
     new_lst = [] 

     c = lst[0] 
     tmp_lst = [c] 

     for i in lst[1:]: 
      if c[:-1] == i[:-1]: 
       c = i 
       tmp_lst.append(c) 
      else: 
       if len(tmp_lst) == 10: 
        new_lst.append(c[:-1]) 
       else: 
        new_lst.extend(tmp_lst) 

       c = i 
       tmp_lst = [c] 

     if len(tmp_lst) == 10: 
      new_lst.append(c[:-1]) 
     else: 
      new_lst.extend(tmp_lst) 

    return lst 
1

我的新的更優化的解決方案(py3.4)

def diap_to_prefix(a, b): 
    def inner(aa, bb, p): 
     if p == 1: 
      if a <= aa <= b: 
       yield aa 
      return 

     for d in range(aa, bb + 1, p): 
      if a <= d and d + p - 1 <= b: 
       yield d // p 
      elif not (bb < a or aa > b): 
       for i in range(10): 
        yield from inner(d + i * p // 10, d + (i + 1) * p // 10 - 1, p // 10) 

    a, b = int(a), int(b) 
    p = 10**(max(len(str(x)) for x in (a, b)) - 1) 
    yield from inner(a // p * p, b // p * p + p - 1, p)