找出2 ^ k以n开头的最小k

时间:2020-02-16 18:13:42

标签: python algorithm decimal

给出一个正整数 n ≤10 7 ,我需要找到最小正整数 k ,使小数表示为2 < sup> k 以小数形式的 n 开头。

例如,如果 n = 12,则 k = 7(因为2 7 == 12 8);如果 n = 134,则 k = 27(因为2 27 == 134 ,217,728);并且如果 n = 82,则 k = 209(因为2 209 8.2 3×10 62 )。

(如果不存在这样的 k ,我需要返回−1。)

我什至没有尝试用公式来解决(我不知道怎么做),而是决定通过计算2的所有幂直至1000的所有幂,将它们放在列表中,然后找到以n开头的数字。该代码有效,但是...它甚至没有通过系统中的第一个测试。我不知道为什么,因为上面的例子可以正常工作。无论如何,这是代码。

def find_all():
    arr = []
    n = 1
    for i in range(1000):
        arr.append(str(n))
        n = n << 1
    return arr


n = str(n)
NOT_FOUND = True
#n = input()
arr = find_all()
for i in arr:
    if i.startswith(n):
        print(arr.index(i), n)
        NOT_FOUND = False
        break
if NOT_FOUND:
    print(-1, n)

有什么问题吗?

1 个答案:

答案 0 :(得分:6)

假设您要查找以123开头的2的幂。

这等效于找到mantissa在0.089905111439398和0.093421685162235之间的log 10 (2)的倍数(因为log 10 (123)= 2.089905111439398并记录 10 (124)= 2.093421685162235)。

如果以这种方式来构造问题,则无需计算2的幂。仅需要一点浮点运算即可。

以下代码工作得很好,但是当n接近10 7 时,会花好几秒钟的时间来产生答案:

def power_of_2_with_prefix(n):
    # Find the minimum integer k such that the digits of 2^k
    # start with the digits of n
    from math import log10
    #
    # First deal with trivial cases
    assert type(n) is int
    if n == 1:
        return 0
    if n < 1:
        return -1
    #
    # Calculate mantissa range
    logmin = log10(n)
    logmax = log10(n+1)
    logmin -= int(logmin)
    logmax -= int(logmax)
    if logmax < logmin:
        logmax += 1
    #
    # Now find a power of 2 whose log10 mantissa lies in this range
    log2 = log10(2)
    # Make sure k is large enough to include all trailing zeros of n
    mink = log10(n) / log10(2)
    x = 1
    k = 0
    while not (logmin <= x < logmax and k >= mink):
        x += log2
        if x >= 1:
            x -= 1
        k += 1
    return k

assert power_of_2_with_prefix(0) == -1
assert power_of_2_with_prefix(1) == 0
assert power_of_2_with_prefix(2) == 1
assert power_of_2_with_prefix(4) == 2
assert power_of_2_with_prefix(40) == 12
assert power_of_2_with_prefix(28584) == 74715
assert power_of_2_with_prefix(28723) == 110057
assert power_of_2_with_prefix(9999999) == 38267831