|
发表于 2017-8-15 16:15:29
|
显示全部楼层
这个是第四版本了,第一版就是直接采用指数统计呀
假设n=2^a*3^b*5^c ,a,b,为大于等于0的整数
n肯定就是汉明数
然后一个个数过去
优化版本是采用log
假设3和5的指数确定了,则2^a *(3^b*5^c)< 10^100
取log2则 a<log2(10^100 / (3^b*5^c)
则a 可以取[0..int(log2(10^100 / (3^b*5^c))]
也就是 int(log2(10^100 / (3^b*5^c))+1个
至于为什么按5 3 2的顺序
是因为2的amax 明显 大于 5的cmax,可以减少迭代次数
贴上2 3 4 4.2版本
- def gethamming2(n):
- amax = int(log(n,2))
- bmax = int(log(n,3))
- cmax = int(log(n,5))
- r = 0
- ap = 1
- for a in range(amax+1):
- abp = ap
- for b in range(bmax+1):
- if abp > n:
- break
- abcp = abp
- for c in range(cmax+1):
- if abcp > n:
- break
- r += 1
- abcp *= 5
- abp *= 3
- ap *= 2
- return r
- def gethamming3(n):
- amax = int(log(n,2))
- bmax = int(log(n,3))
- r = 0
- ap = 1
- for a in range(amax+1):
- abp = ap
- for b in range(bmax+1):
- if abp > n:
- break
- r += 1 + int(log(n/abp, 5)) #1 include c==0
- abp *= 3
- ap *= 2
- return r
- def gethamming4(n):
- bmax = int(log(n,3))
- cmax = int(log(n,5))
- r = 0
-
- cp = 1
- for c in range(cmax+1):
- cbp = cp
- for b in range(bmax+1):
- if cbp > n:
- break
- #2 loop times =[0..log2(n/cbp)]
- r += 1 + int(log(n/cbp,2)) #1 include a==0
- cbp *= 3
- cp *= 5
- return r
复制代码
#Win7 64+Python 3.62 64 + AMD Phenom II X4 965 + DDR3*8G
st = time.time()
print(gethamming2(10**100)) #1697191
t = time.time()-st
print("V2 cost", t) #1=3.5(use **) #2=0.3240184783935547
st = time.time()
print(gethamming3(10**100)) #1697191
t = time.time()-st
print("V3 cost", t) #3=0.04100227355957031
st = time.time()
print(gethamming4(10**100)) #1697191
t = time.time()-st
print("V4 cost", t) #4=0.017000913619995117
st = time.time()
print(gethamming4_2(10**100)) #1697191
t = time.time()-st
print("V4.2 cost", t) #4.2=0.016000747680664062 |
|