题目:
任意给定一个正整数n,计算0~n中1的个数。
例如:
输入:5
0~5的二进制为:
000,
001,
010,
011,
100,
101;
那么1的个数是1+1+2+1+2=7
输出:7
拿到这道题目,首先想到的是将n转化为二进制数,然后做循环,依次判断n的二进制数的每一位,若是1,则sum++;然后计算n+1,按照第一步的方法。
给出Python代码:
class getSum():
def __init__(self,i):
self.i=i
self.sum=0
def __getsum__(self):
for k in xrange(0,self.i+1):
binary_k = self.__getbin__(k)
for i in binary_k:
if i=='1':
self.sum+=1
return self.sum
def __getbin__(self,j):
binary_j=bin(j).replace('0b', '')
return binary_j
这是最笨的方法,时间复杂度相当高。
另一种方法:
将n和n-1做“&”操作,得出的结果若不为0,那么就是n从低位到高位上的第一个1;然后令n=n&(n-1),再根据上述判断n&(n-1),直到结果为0.
给出Python代码:
class getNeighbor():
def __init__(self,i):
self.i=i
self.sum=0
def __getsum__(self):
for k in xrange(0,self.i+1):
sum_k = 0
while(k):
sum_k+=1
k=k&(k-1)
self.sum += sum_k
return self.sum
最后给出测试代码:
# -*- coding:utf-8 -*-
# __author__ = 'hhb'
import time
class getSum():
def __init__(self,i):
self.i=i
self.sum=0
def __getsum__(self):
for k in xrange(0,self.i+1):
binary_k = self.__getbin__(k)
for i in binary_k:
if i=='1':
self.sum+=1
return self.sum
def __getbin__(self,j):
binary_j=bin(j).replace('0b', '')
return binary_j
class getNeighbor():
def __init__(self,i):
self.i=i
self.sum=0
def __getsum__(self):
for k in xrange(0,self.i+1):
sum_k = 0
while(k):
sum_k+=1
k=k&(k-1)
self.sum += sum_k
return self.sum
def main(n):
print "You have input an integer: %d" %n
t_beg = time.time()
obj_1 = getSum(n)
sum = obj_1.__getsum__()
t_end = time.time()
print "The getSum method total get 1: %d" % sum
dt=t_end-t_beg
print "Total time used: %s"%dt
t_beg = time.time()
obj_2 = getNeighbor(n)
sum = obj_2.__getsum__()
t_end = time.time()
print "The getNeighbor method total get 1: %d" % sum
dt = t_end - t_beg
print "Total time used: %s" % dt
if __name__=="__main__":
n = int(raw_input("Input an integer:"))
main(n)
给出当n=5000时候的测试结果:
第二种方法果然更快!