2016-08-13 89 views
2

我想要一个无限循环的前9个数字和最后9个数字的斐波那契数列。单独运行测试,使用模数运算符no得到比前9位数字更好的最后9位数的结果。我跑了像int(str(b)[::-1])%10**9, b/(10**(len(str(b))-9))不同的测试,但仍然是相同的结果。我认为这是因为数字到字符串转换的高位数字。有没有其他方法可以打印前9位数字而不用转换成字符串或使用/不使用字符串的有效方式?数字的第一位

def fibby(): 
    a,b = 1,1 
    yield [a,a] 
    yield [b,b] 
    while True: 
     a,b = b,a+b 
     yield [str(b)[:9], b%10**9] 
+0

你所说的 “更好的结果” 是什么意思?你获得了哪些结果?他们有什么错误? – ypnos

+2

我不确定它会比将整个数字转换为字符串更高效,但您可以使用'math.log10()'来计算数字,'//'做一个整数除法来获取最重要的数字。 –

+0

我的意思是在时间表现方面。例如,最低有效位在6秒钟内弹出10 ** 8,而MSB需要2分钟以上(单独测试)。 MSB可以成为LSB的时间匹配吗? –

回答

1

以下是获取第一个30000前缀的几个版本和计时。为了简单起见,我忽略了前两个收益率和最后一位数字。

  • fibby1是刚使用str(b)[:9]的原始方式。
  • fibby2记录10除以的适当能力。
  • fibby3保留ab中的前9位数字,其余数字位于AB。与fibby2相比,这样可以避免用大的幂数来划分大的数字。大数字只能被加/减/比较,或乘以一个很小的数字。
  • fibby4使用math.log10由@therefromhere建议。
  • fibby5使用decimal模块。

输出:

All agree? True 
fibby1: 24.835 seconds 
fibby2: 0.289 seconds 
fibby3: 0.201 seconds 
fibby4: 2.802 seconds 
fibby5: 0.216 seconds 

只是为了比较,我也试过str(b % 10**9),即最后9个位数,而把0.506秒。哪个是慢于比我的前九位数的快速解决方案。

代码:

def fibby1(): 
    a, b = 1, 1 
    while True: 
     yield str(b)[:9] 
     a, b = b, a+b 

def fibby2(): 
    a, b = 1, 1 
    div = 1 
    while True: 
     while True: 
      front = b // div 
      if front < 10**9: 
       break 
      div *= 10 
     yield str(front) 
     a, b = b, a+b 

def fibby3(): 
    a,b = 1,1 
    A,B,C = 0,0,1 
    while True: 
     yield str(b) 
     a, b = b, a+b 
     A, B = B, A+B 
     if B >= C: 
      B -= C 
      b += 1 
     if b >= 10**9: 
      A += a%10 * C 
      B += b%10 * C 
      a //= 10 
      b //= 10 
      C *= 10 

def fibby4(): 
    from math import log10 
    a, b = 1, 1 
    while True: 
     yield str(b // 10**max(0, int(log10(b) - 8))) 
     a, b = b, a+b 

def fibby5(): 
    from decimal import Decimal, getcontext 
    getcontext().prec = 7000 # enough for n = 30000 
    a, b = Decimal(1), Decimal(1) 
    while True: 
     yield str(b)[:9] 
     a, b = b, a+b 

from timeit import timeit 
from itertools import islice 
from time import time 

n = 30000 
t0 = time() 
list1 = list(islice(fibby1(), n)) 
t1 = time() 
list2 = list(islice(fibby2(), n)) 
t2 = time() 
list3 = list(islice(fibby3(), n)) 
t3 = time() 
list4 = list(islice(fibby4(), n)) 
t4 = time() 
list5 = list(islice(fibby5(), n)) 
t5 = time() 
print('All agree?', list1 == list2 == list3 == list4 == list5) 
print('fibby1: %6.3f seconds' % (t1 - t0)) 
print('fibby2: %6.3f seconds' % (t2 - t1)) 
print('fibby3: %6.3f seconds' % (t3 - t2)) 
print('fibby4: %6.3f seconds' % (t4 - t3)) 
print('fibby5: %6.3f seconds' % (t5 - t4)) 
相关问题