给定n,计算二进制0b(0,...,n)中的1的个数

题目:
任意给定一个正整数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时候的测试结果:
这里写图片描述

第二种方法果然更快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值