【问题标题】:Fibonacci Adder Machine - Calculating Digits in Fibonacci Sequence斐波那契加法器 - 计算斐波那契数列中的数字
【发布时间】:2020-01-18 18:47:15
【问题描述】:

我正在开发一个程序,该程序将计算具有某些数字限制的斐波那契数(即第一个具有 100 位数字的斐波那契数)。下面的代码总体上正在运行,但我遇到了一个让我难过的逻辑错误。

代码的目标是以类似于二进制加法的方式计算斐波那契数。使用数组,每个元素都保存一个从 0 到 9 的数字,因此每个数组索引代表一个 10 的位置。

它开始工作并正常循环,但由于处理循环的方式,它在 13 到 21 之间停止。它将数字与 10 的位置相加,然后保存一个 31 数字。

有没有办法打破或阻止它把我没有看到的那些加在一起?

num1 = [0]*100
num2 = [0]*100
num2[len(num2)-1] = 1
carry = 0
flag = True

while (flag):
    #Main for loop to work through the array
    for count in range (1, len(num2)):
        carry = num2[len(num2) - count] + num1[len(num1) - count]
        if carry > 9:
            num2[len(num2)- (count + 1)] = num2[len(num2)- (count + 1)] + 1
            carry = carry % 10
            num1[len(num1) - count] = num2[len(num2) - count]
            num2[len(num2) - count] = carry
        else:
            num1[len(num1) - count] = num2[len(num2) - count]
            num2[len(num2) - count] = carry
    print(num2)
    if num2[0] != 0:
        flag = False

每次它通过我希望看到的主 while 循环

[0,0,...,0,1]
[0,0,...,0,2]
[0,0,...,0,3]
[0,0,...,0,5]
[0,0,...,0,8]
[0,0,...,1,3]
[0,0,...,2,1]
...

但在它到达 [...,2,1] 循环后,它会移动到 [...,3,1]

【问题讨论】:

  • 缺少 num1 的定义。是否为num2(除了右边全为0)?
  • 它在里面,一定不是每次我抓取代码粘贴到这里时都复制它。我将进行编辑,以便更清楚。
  • @LukeMorris,我不太清楚你的输出应该是什么?你能在你的问题中澄清一下吗?
  • 错误已经出现在 num2 = 8 和 num1 = 5 时,在第一次进位时:在 count = 1 时将 num2 修改为 13,然后在 count = 2 时使用该 1(进位)来总和到 num1 得到 15 而不是 8 如预期的那样。使用调试器 ;-) 我猜你可能记得有一个进位并在下一次计数时减去它,或者你需要改变你的逻辑来更新新的 1 和 2
  • 我会说,记住在下一个循环中要添加进位,但不要在当前数字中添加。这应该是最好的!

标签: python loops fibonacci


【解决方案1】:

这是对您的代码的更正。请注意,Python 具有无限精度整数,因此我添加了一个斐波那契生成器来检查答案。

num1 = [0]*100
num2 = [0]*100
num2[len(num2)-1] = 1
flag = True

# Fibonacci generator for verification of answer
def fib():
    a,b = 0,1
    while True:
        a,b = b,a+b
        yield a

# Instance of the generator
f = fib()

# convert a list of single-digit integers to a real integer for display
def value(L):
    assert all(n < 10 for n in L) # bug checking for invalid list values.
    return int(''.join([str(i) for i in L]))

while (flag):
    #Main for loop to work through the array

    # Start with zero carry for first digit
    carry = 0

    for count in range (1,len(num2)+1): # originally off-by-1.

        # compute the sum plus the carry of previous sum
        temp = num2[len(num2) - count] + num1[len(num1) - count] + carry

        # shift num2 digit to num1 digit
        num1[len(num1) - count] = num2[len(num2) - count]

        # new num2 digit is the one's place of temp sum.
        num2[len(num2) - count] = temp % 10

        # remember the carry (10's place) for next sum.
        carry = temp // 10

    # Check for bugs...compare the answer with the next Fibonacci number
    assert value(num1) == next(f)

    if num1[0] != 0:
        flag = False

print(value(num1))

请注意,您可以通过记住负偏移量从末尾访问数组(num2[-1] 是数组中的最后一项)和range 可以倒数来使 for 循环更简单:

for count in range(-1,-len(num2)-1,-1):
    temp = num2[count] + num1[count] + carry
    num1[count] = num2[count]
    num2[count] = temp % 10
    carry = temp // 10 # remember carry for next digit

【讨论】:

    【解决方案2】:

    它比我的 cmets 更棘手,但这个版本可以正常工作:

    num1 = [0]*10
    num2 = [0]*10
    num2[len(num2)-1] = 1
    sum = 0
    carry = 0
    flag = True
    
    while (flag):
        #Main for loop to work through the array
        for count in range (1, len(num2)):
            sum = num2[len(num2) - count] + num1[len(num1) - count] + carry
            num1[len(num1) - count] = num2[len(num2) - count]
            if sum > 9:
                sum = sum % 10
                carry = 1
            else:
                carry = 0
            num2[len(num2) - count] = sum
        if carry == 1:
            num2[0] = num2[0] + 1
        print(num2)
        if num2[0] != 0:
            flag = False
    

    您还必须在应用进位之前复制到 new1,即使是在下一个较高位执行此操作时...

    【讨论】:

      【解决方案3】:

      这是我认为您想要了解的内容的一个更简洁的版本。

      #Init of Fib variables 
      a = 0
      b = 1
      num = 10  #Change this to the number of fib calculation loops.
      x = 0
      output_arr_len = 100 #Change this to 10 for testing, as it's easier to see.    
      
      while x < num:
          #Calculate Fib Sequence
          c = a + b 
          a = b
          b = c 
          x += 1
      
          #Output Array
          print([0] * (output_arr_len - len(str(c))) + [int(i) for i in str(c)])
      

      下面是前 20 个循环的输出,output_arr_len 设置为 10。

      [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 5]
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 8]
      [0, 0, 0, 0, 0, 0, 0, 0, 1, 3]
      [0, 0, 0, 0, 0, 0, 0, 0, 2, 1]
      [0, 0, 0, 0, 0, 0, 0, 0, 3, 4]
      [0, 0, 0, 0, 0, 0, 0, 0, 5, 5]
      [0, 0, 0, 0, 0, 0, 0, 0, 8, 9]
      [0, 0, 0, 0, 0, 0, 0, 1, 4, 4]
      [0, 0, 0, 0, 0, 0, 0, 2, 3, 3]
      [0, 0, 0, 0, 0, 0, 0, 3, 7, 7]
      [0, 0, 0, 0, 0, 0, 0, 6, 1, 0]
      [0, 0, 0, 0, 0, 0, 0, 9, 8, 7]
      [0, 0, 0, 0, 0, 0, 1, 5, 9, 7]
      [0, 0, 0, 0, 0, 0, 2, 5, 8, 4]
      [0, 0, 0, 0, 0, 0, 4, 1, 8, 1]
      [0, 0, 0, 0, 0, 0, 6, 7, 6, 5]
      [0, 0, 0, 0, 0, 1, 0, 9, 4, 6]
      

      【讨论】:

      • 您的答案有效,但不适用于任意大的值,因为您依赖于整数最大值。这个问题,真正逐位工作,而不是仅以这种方式显示,更通用......
      • @B.Go Python 中没有整数最大值(视内存而定),这让我想知道为什么 OP 会这样做。
      • @MarkTolonen 好的,感谢您提供的信息。但我仍然认为使用与问题中相同的算法更好的答案,并且应该修复该算法,而不是使用不同的算法!
      猜你喜欢
      • 1970-01-01
      • 2013-03-31
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 2015-06-05
      • 2013-08-12
      相关资源
      最近更新 更多