3

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

3331234-3332345

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

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

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

4

5 回答 5

1

My working code. It not very quick, too. Optimizations welcome.

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
于 2015-10-28T12:23:01.517 回答
1

My new more optimal solution (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)
于 2015-10-28T13:52:21.053 回答
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)]
于 2012-04-15T20:17:20.543 回答
0

Here's a sketch of one way to handle this problem. I've used ellipses to mark the spots where you'll need to fill in the details explained in the comments. I'd write a function to derive the initial value of 'maxpower', everything else is simple enough to be written inline.

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
于 2012-04-16T01:21:17.680 回答
0

My working code. It not very quick, but working. Optimizations welcome.

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, '')
于 2012-05-14T12:38:06.457 回答