zoukankan      html  css  js  c++  java
  • 1的个数

    int Count(unsigned int v)
    {
        int num = 0;
        
        while(v)
        {
             v &= (v-1);
             num++;
        }
        return num;
    }

    这种方法速度比较快,其运算次数与输入n的大小无关,只与n中1的个数有关。如果n的二进制表示中有k个1,那么这个方法只需要循环k次即可。

    其原理是不断清除n的二进制表示中最右边的1,同时计数器加1,直至n为0

    对于int 型32位的呢

    def NumberOf1( n):
        min_val=-2**31
        if n ==min_val:
            return 1
        if n>=0:
            num=0
        else:
            num=1
        while n!=0 and n>min_val:
            n&=n-1
            num+=1
    
        return num

     int型32位表示范围为-2^31~2^31-1,最高位表示符号位,负数比正数多一位,多的这以为就是100000000000000,就是-0,也就是-2^31。

    在判断1的个数的时候,负数的符号位也为1,所以也要加入判断,所以如果n为负数,则初始化的时候,num=1

    计算十进制数中1的个数

     给定一个数n,计算从1~n中所有数字中出现1的次数总和。

    f(13)=6

    f(23)=13

    f(24)=14

    通过分析发现:f(n)=个位出现1的次数+十位出现1的次数+百位出现1的次数+...

    某一位出现1的个数总结,以十位为例

    如果十位是0:以1101为列,十位出现1的个数10~19,110~119,210~219,...,910~919,1010~1019共计110个,说白了就是在十位出现1(10~19)的情况下,最高的两位可以不停的变化,从00~10,共00,01,02,..,10,共计11种情况,每种情况下都对应低位的(10~19)10个,所以共计110个出现1。总结为highNum*factor(如果是计算十位个数,factor=10,百位factor=100)

    如果十位是1:同上分析,则为highNum*factor+lowerNum+1,多了一个低位数加1,就是既与高位数有关,也与低位数有关。

    如果十位大于1:则为(highNum+1)*factor。

    def sum1s(n):
        count=0
        factor=1
        while n//factor:
            lowerNum=n%factor
            currNum=(n//factor)%10
            highNum=n//(factor*10)
            if currNum==0:
                count+=highNum*factor
            elif currNum==1:
                count+=highNum*factor+lowerNum+1
            else:
                count+=(highNum+1)*factor
            factor*=10
        return count

     这样的话计算一个1~n数中,所有出现1的个数时间复杂度为O(log10(n)),也就是只与n的位数有关系了。

  • 相关阅读:
    几种常见的树:排序二叉树、平衡二叉树、红黑树、B+树
    网关高可用
    微服务网关GateWay
    微服务网关Zuul
    客户端容错保护Alibaba Sentinel
    客户端容错保护Hystrix
    服务调用Feign
    服务注册与发现Consul
    服务负载均衡调用Ribbon
    服务注册Eureka高级
  • 原文地址:https://www.cnblogs.com/gczr/p/8086223.html
Copyright © 2011-2022 走看看