我试图创建一个接收数字作为参数的函数,并对该数字执行操作以找出其最接近的2的幂,然后将该数加起来。例如,如果用户输入4,则该函数将附加4,因为它已经是2的幂。如果用户输入14,则该函数应该看到14不是2的幂,并且最接近2的幂组成14是2,4和8。
主要提示: 我只上升到2 ^ 9。
到目前为止:
def powers_finder(n):
powers=[]
i=0
total=0
while i<10:
value=2**i
total=total+value
i=i+1
#This if statement is for if the user enters a power of 2 as n
#Then the number will be appended right away into my powers list.
if value==n:
powers.append(value)
这里的问题是,如果用户输入,则假设5为(n)5由功率2 ^ 2 = 4和2 ^ 0 = 1 4 + 1 = 5组成。如何扩展我的功能以包含此过程?
谢谢你!答案 0 :(得分:13)
最有效的方法:
def myfunc(x):
powers = []
i = 1
while i <= x:
if i & x:
powers.append(i)
i <<= 1
return powers
答案 1 :(得分:2)
尝试使用二进制文件:
def power_find(n):
result = []
binary = bin(n)[:1:-1]
for x in range(len(binary)):
if int(binary[x]):
result.append(2**x)
return result
>>> power_find(11)
[1, 2, 8]
答案 2 :(得分:2)
当然,最好和最快的方法是使用二进制数字,但这是使用生成器的方法:
def powers_finder(num):
d = []
while sum(d) < num:
p = powers_of_2()
a=b=1
while sum(d)+a<=num:
b=a
a = next(p)
d.append(b)
d.reverse()
return d
def powers_of_2():
n=1
while 1:
yield n
n*=2
>>> print(powers_finder(5))
[1, 4]
>>> print(powers_finder(8))
[8]
>>> print(powers_finder(9))
[1, 8]
>>> print(powers_finder(14))
[2, 4, 8]
答案 3 :(得分:1)
一种简单(但实际上并非有效)的方法是使用回溯。请注意,使用math.log
函数( n 中最接近2的幂为2^round(log(n, 2))
)可以很容易地确定2的最接近幂:
from math import log
def powers_finder(n):
return powers_finder_rec(n, [2**x for x in range(round(log(n, 2)+1))])
def powers_finder_rec(n, powers):
if sum(powers) == n:
return powers
for i, j in enumerate(powers):
(res1, res2) = (powers_finder_rec(n-j, powers[:i] + powers[i+1:]),
powers_finder_rec(n, powers[:i] + powers[i+1:]))
if res1 or res2:
return [j] + res1 if res1 else res2
return []
print(powers_finder(13))
print(powers_finder(112))
输出:
[1, 4, 8]
[16, 32, 64]
答案 4 :(得分:1)
这个想法是将数字转换为二进制,然后从二进制表示中获得2的幂:
#!/usr/bin/env python
def get_powers(n):
"""Get positive powers of two which add up to n.
Parameters
----------
n : positive integer
Returns
-------
list of integers which are powers of 2
Examples
--------
>>> get_powers(14)
[2, 4, 8]
>>> get_powers(5)
[1, 4]
"""
get_bin = lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
bin_str = get_bin(n) # convert n to a binary string
powers = []
for i, digit in enumerate(bin_str[::-1]):
if digit == '1':
powers.append(2**i)
return powers
答案 5 :(得分:1)
以下二元解决方案结合了@ moose对enumerate()
的使用和@ gbriones.gdl对stride索引的使用以及@ gbriones.gdl关于单行的评论(实际上,这是关于不是<的评论/ em> one-lining it,但one-lining很有趣。)
def powers(n):
return [2**p for p,v in enumerate(bin(n)[:1:-1]) if int(v)]
答案 6 :(得分:1)
我们现在对这个问题有一些很好的答案。我想我会用dis
和timeit
来分析它们。
以下是我使用的测试代码:
import dis
import timeit
def gbriones_gdl(num):
result = []
binary = bin(num)[:1:-1]
for x in range(len(binary)):
if int(binary[x]):
result.append(2**x)
return result
def nullptr(num):
powers = []
i = 1
while i <= num:
if i & num:
powers.append(i)
i <<= 1
return powers
def t3_gen(num):
d = []
while sum(d) < num:
p = powers_of_2()
a=b=1
while sum(d)+a<=num:
b=a
a = next(p)
d.append(b)
d.reverse()
return d
def powers_of_2():
n=1
while 1:
yield n
n*=2
def t3_enum(num):
return [2**p for p,v in enumerate(bin(num)[:1:-1]) if int(v)]
def moose(num):
get_bin = lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
bin_str = get_bin(num) # convert num to a binary string
powers = []
for i, digit in enumerate(bin_str[::-1]):
if digit == '1':
powers.append(2**i)
return powers
print('Each function gives correct results:', nullptr(1048575) == moose(1048575) ==
t3_enum(1048575) == gbriones_gdl(1048575) ==
t3_gen(1048575))
print()
print('nullptr'.ljust(15), timeit.timeit('nullptr(1048575)', 'from __main__ import nullptr', number=100000))
print('moose'.ljust(15), timeit.timeit('moose(1048575)', 'from __main__ import moose', number=100000))
print('t3_enum'.ljust(15), timeit.timeit('t3_enum(1048575)', 'from __main__ import t3_enum', number=100000))
print('gbriones_gdl'.ljust(15), timeit.timeit('gbriones_gdl(1048575)', 'from __main__ import gbriones_gdl', number=100000))
print('t3_gen'.ljust(15), timeit.timeit('t3_gen(1048575)', 'from __main__ import t3_gen', number=100000))
print('\nnullptr:\n===========================')
print(dis.dis(nullptr))
print('\nmoose:\n===========================')
print(dis.dis(moose))
print('\nt3_enum:\n===========================')
print(dis.dis(t3_gen))
print('gbriones_gdl:\n===========================')
print(dis.dis(t3_enum))
print('\nt3_gen:\n===========================')
print(dis.dis(gbriones_gdl))
以下是结果:
Each function gives correct results: True
nullptr 0.7847449885390462
moose 1.810839785503465
t3_enum 2.898256901365956
gbriones_gdl 3.0904670146624778
t3_gen 21.366890624367063
nullptr:
===========================
14 0 BUILD_LIST 0
3 STORE_FAST 1 (powers)
15 6 LOAD_CONST 1 (1)
9 STORE_FAST 2 (i)
16 12 SETUP_LOOP 52 (to 67)
>> 15 LOAD_FAST 2 (i)
18 LOAD_FAST 0 (num)
21 COMPARE_OP 1 (<=)
24 POP_JUMP_IF_FALSE 66
17 27 LOAD_FAST 2 (i)
30 LOAD_FAST 0 (num)
33 BINARY_AND
34 POP_JUMP_IF_FALSE 53
18 37 LOAD_FAST 1 (powers)
40 LOAD_ATTR 0 (append)
43 LOAD_FAST 2 (i)
46 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
49 POP_TOP
50 JUMP_FORWARD 0 (to 53)
19 >> 53 LOAD_FAST 2 (i)
56 LOAD_CONST 1 (1)
59 INPLACE_LSHIFT
60 STORE_FAST 2 (i)
63 JUMP_ABSOLUTE 15
>> 66 POP_BLOCK
20 >> 67 LOAD_FAST 1 (powers)
70 RETURN_VALUE
None
moose:
===========================
44 0 LOAD_CONST 1 (<code object <lambda> at 0x0000000002A8E660, file "power_2_adder.py", line 44>)
3 LOAD_CONST 2 ('moose.<locals>.<lambda>')
6 MAKE_FUNCTION 0
9 STORE_FAST 1 (get_bin)
45 12 LOAD_FAST 1 (get_bin)
15 LOAD_FAST 0 (num)
18 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
21 STORE_FAST 2 (bin_str)
46 24 BUILD_LIST 0
27 STORE_FAST 3 (powers)
47 30 SETUP_LOOP 71 (to 104)
33 LOAD_GLOBAL 0 (enumerate)
36 LOAD_FAST 2 (bin_str)
39 LOAD_CONST 0 (None)
42 LOAD_CONST 0 (None)
45 LOAD_CONST 6 (-1)
48 BUILD_SLICE 3
51 BINARY_SUBSCR
52 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
55 GET_ITER
>> 56 FOR_ITER 44 (to 103)
59 UNPACK_SEQUENCE 2
62 STORE_FAST 4 (i)
65 STORE_FAST 5 (digit)
48 68 LOAD_FAST 5 (digit)
71 LOAD_CONST 4 ('1')
74 COMPARE_OP 2 (==)
77 POP_JUMP_IF_FALSE 56
49 80 LOAD_FAST 3 (powers)
83 LOAD_ATTR 1 (append)
86 LOAD_CONST 5 (2)
89 LOAD_FAST 4 (i)
92 BINARY_POWER
93 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
96 POP_TOP
97 JUMP_ABSOLUTE 56
100 JUMP_ABSOLUTE 56
>> 103 POP_BLOCK
50 >> 104 LOAD_FAST 3 (powers)
107 RETURN_VALUE
None
t3_enum:
===========================
23 0 BUILD_LIST 0
3 STORE_FAST 1 (d)
24 6 SETUP_LOOP 101 (to 110)
>> 9 LOAD_GLOBAL 0 (sum)
12 LOAD_FAST 1 (d)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
18 LOAD_FAST 0 (num)
21 COMPARE_OP 0 (<)
24 POP_JUMP_IF_FALSE 109
25 27 LOAD_GLOBAL 1 (powers_of_2)
30 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
33 STORE_FAST 2 (p)
26 36 LOAD_CONST 1 (1)
39 DUP_TOP
40 STORE_FAST 3 (a)
43 STORE_FAST 4 (b)
27 46 SETUP_LOOP 44 (to 93)
>> 49 LOAD_GLOBAL 0 (sum)
52 LOAD_FAST 1 (d)
55 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
58 LOAD_FAST 3 (a)
61 BINARY_ADD
62 LOAD_FAST 0 (num)
65 COMPARE_OP 1 (<=)
68 POP_JUMP_IF_FALSE 92
28 71 LOAD_FAST 3 (a)
74 STORE_FAST 4 (b)
29 77 LOAD_GLOBAL 2 (next)
80 LOAD_FAST 2 (p)
83 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
86 STORE_FAST 3 (a)
89 JUMP_ABSOLUTE 49
>> 92 POP_BLOCK
30 >> 93 LOAD_FAST 1 (d)
96 LOAD_ATTR 3 (append)
99 LOAD_FAST 4 (b)
102 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
105 POP_TOP
106 JUMP_ABSOLUTE 9
>> 109 POP_BLOCK
31 >> 110 LOAD_FAST 1 (d)
113 LOAD_ATTR 4 (reverse)
116 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
119 POP_TOP
32 120 LOAD_FAST 1 (d)
123 RETURN_VALUE
None
gbriones_gdl:
===========================
41 0 LOAD_CONST 1 (<code object <listcomp> at 0x0000000002A8E540, file "power_2_adder.py", line 41>)
3 LOAD_CONST 2 ('t3_enum.<locals>.<listcomp>')
6 MAKE_FUNCTION 0
9 LOAD_GLOBAL 0 (enumerate)
12 LOAD_GLOBAL 1 (bin)
15 LOAD_FAST 0 (num)
18 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
21 LOAD_CONST 0 (None)
24 LOAD_CONST 3 (1)
27 LOAD_CONST 4 (-1)
30 BUILD_SLICE 3
33 BINARY_SUBSCR
34 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
37 GET_ITER
38 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
41 RETURN_VALUE
None
t3_gen:
===========================
6 0 BUILD_LIST 0
3 STORE_FAST 1 (result)
7 6 LOAD_GLOBAL 0 (bin)
9 LOAD_FAST 0 (num)
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
15 LOAD_CONST 0 (None)
18 LOAD_CONST 1 (1)
21 LOAD_CONST 3 (-1)
24 BUILD_SLICE 3
27 BINARY_SUBSCR
28 STORE_FAST 2 (binary)
8 31 SETUP_LOOP 62 (to 96)
34 LOAD_GLOBAL 1 (range)
37 LOAD_GLOBAL 2 (len)
40 LOAD_FAST 2 (binary)
43 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
46 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
49 GET_ITER
>> 50 FOR_ITER 42 (to 95)
53 STORE_FAST 3 (x)
9 56 LOAD_GLOBAL 3 (int)
59 LOAD_FAST 2 (binary)
62 LOAD_FAST 3 (x)
65 BINARY_SUBSCR
66 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
69 POP_JUMP_IF_FALSE 50
10 72 LOAD_FAST 1 (result)
75 LOAD_ATTR 4 (append)
78 LOAD_CONST 2 (2)
81 LOAD_FAST 3 (x)
84 BINARY_POWER
85 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
88 POP_TOP
89 JUMP_ABSOLUTE 50
92 JUMP_ABSOLUTE 50
>> 95 POP_BLOCK
11 >> 96 LOAD_FAST 1 (result)
99 RETURN_VALUE
None
从timeit
结果中,我们可以看到@ nullptr的解决方案非常好,正如我所怀疑的那样,其次是@ moose的解决方案。之后是@ moose和@ gbriones.gdl解决方案的组合,紧跟@ gbriones.gdl的解决方案。我们说,我的发电机解决方案非常不理想,但我有点期待。
dis
结果包含完整性。
答案 7 :(得分:0)
而不是解决问题,如何帮助您解决一些信息呢?看一些例子,然后解决它们。以下是一些,
假设N = 2,那么答案是= {2 = 2 ^ 1}。
假设N = 3,那么答案是= {2 = 2 ^ 1,1 = 2 ^ 0}(注意2 ** 0 = 1)
假设N = 4,那么答案是= {4 = 2 ^ 2}
...
假设N = 63,那么答案是= {32 = 2 ^ 5,16 = 2 ^ 4,8 = 2 ^ 3,4 = 2 ^ 2,2 = 2 ^ 1,1 = 2 ^ 0}
假设N = 64,那么答案是= {64 = 2 ^ 6}
...
假设N = 259,那么答案是= {256 = 2 ^ 8,2 = 2 ^ 1,1 = 2 ^ 0}
你看到了模式吗?
想要算法吗?
考虑这些简单的步骤,并将它们组合在一起,
你能检查这个号码是否奇怪吗?当数字是奇数时,你已经检测到一点'开'。减1(使数字均匀)。
你可以除以2吗?你怎么处理结果?