【问题标题】:Converting phone number range list to prefix list将电话号码范围列表转换为前缀列表
【发布时间】:2012-04-15 20:08:20
【问题描述】:

我有一个电话号码范围,例如:

3331234-3332345

我需要编写一个将其转换为前缀列表的函数:

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

问题没那么容易。我不需要获取范围开始和结束之间的数字列表。

【问题讨论】:

  • 您自己尝试过任何东西吗?我们不是来为您编写完整的解决方案。在其他新闻中,前缀到底是什么?我假设333,但你的问题没有具体说明。
  • 我不是在寻找代码。我正在寻找方向。前缀是最长的“字符串”,包含完整的 10、100 或 1000 等等。

标签: python phone-number


【解决方案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

【讨论】:

    【解决方案2】:

    我的新的更优化的解决方案(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)
    

    【讨论】:

      【解决方案3】:

      你需要得到用“-”分隔的值的公共前缀,所以:

      • 使用.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)]
      

      【讨论】:

      • 检查我的前缀列表。有时它只有 5 位数字,因为它涵盖了完整的 100 个数字,例如前缀 33313 ... 33319 涵盖了 3331300 和 3331999 之间的所有数字
      • @vpol 好的,抱歉,你的问题不清楚……你能再澄清一点吗?
      • @vpol 所以,你应该得到这 2 个号码的公共部分,并从中得到一个 7 位数的电话号码列表,对吗?
      • 是的。但数字长度是一个变量。应该使用某种递归......但不能写算法
      • m = int(R[0]+"0"*(phone_len-len(R[0])))
      【解决方案4】:

      这是处理此问题的一种方法的草图。我使用省略号来标记您需要填写 cmets 中解释的详细信息的位置。我会编写一个函数来导出 '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
      

      【讨论】:

        【解决方案5】:

        我的工作代码。它不是很快,但工作。欢迎优化。

        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, '')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-07
          • 1970-01-01
          • 2012-07-13
          • 2017-10-02
          • 1970-01-01
          • 2016-10-24
          • 2020-01-21
          相关资源
          最近更新 更多