简体   繁体   English

斐波那契数和的最后一位数

[英]Last Digit of the Sum of Fibonacci Numbers

I am trying to find the last digit of sum of Fibonacci Series.我试图找到斐波那契数列总和的最后一位数字。 I calculate the sum as F(n+2) - 1 .我将总和计算为F(n+2) - 1 The below code is working fine but it is slow for large numbers (eg 99999 ).下面的代码工作正常,但对于大数字(例如99999 )来说速度很慢。 How can I optimize this?我怎样才能优化这个?

n = int(input())

def last_digit(n):
    a, b = 0, 1
    for i in range(n+2):
        a, b = b, a + b
    return (a-1) % 10

print(last_digit(n))

The series of final digits of Fibonacci numbers repeats with a cycle of 60. Therefore, you can optimize the calculation of the sum of n terms to F((n+2) % 60) - 1 .斐波那契数列的最后一位数以 60 为周期重复。因此,您可以将 n 项之和的计算优化为F((n+2) % 60) - 1 Also, to stay in the integer range, you can keep only the last digit of each term:此外,为了保持在整数范围内,您可以只保留每一项的最后一位数字:

def last_digit(n):
    a, b = 0, 1
    for i in range((n + 2) % 60):
        a, b = b, (a + b) % 10
    return 9 if a == 0 else a - 1

print([last_digit(n) for n in range(1, 11)])

Output:输出:

[1, 2, 4, 7, 2, 0, 3, 4, 8, 3]

Look at this table: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html notice that fib(60) last digit is 0 and fib(61) last digit is 1 , that is same as fib(0) and fib(1) , thus starting at 60 last digits starts to repeat, so you can calculate last digit for fib(n%60) rather than fib(n) .看看这个表: http : //www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html注意fib(60)最后一位数字是0fib(61)最后一位数字是1 ,这与fib(0)fib(1) ,因此从60最后一位开始重复,因此您可以计算fib(n%60)而不是fib(n)最后一位。 For example last digit is same for fib(115) and fib(55) and equal to 5 .例如, fib(115)fib(55)最后一位数字相同并且等于5

Here's code optimized specifically for the last digit:这是专门针对最后一位数字优化的代码:

def fib(n):
    a, b = 0, 1
    r = 1
    if n < 1:
        return 0
    for i in range(n - 1):
        a, b = b, (a + b)%10
        r += b
        r %= 10
    return r

It works by getting only the last digit of the next term and adding that to the result.它的工作原理是仅获取下一项的最后一位数字并将其添加到结果中。 It then gets the last digit of the result and sets it to itself.然后它获取结果的最后一位数字并将其设置为自身。 It repeats until it gets to the term number and returns a one-digit number :D它重复直到到达术语编号并返回一位数:D

Fun Fact: Try the above function on 99. Returns 0. What about 999?有趣的事实:在 99 上尝试上述函数。返回 0。那么 999 呢? 0. 9999? 0. 9999? 0. Continue this :D 0. 继续这个 :D

Try to use the Pisano Period property .尝试使用Pisano Period 属性 If you want to compute the last digit, Pisano Period of 10 will be 60. Knowing this, you can have a function similar to:如果要计算最后一位数字,则 10 的 Pisano 周期将为 60。知道这一点,您可以使用类似于以下内容的函数:

def fibonacci_sum(n):

    pisano = 60

    if n < 2: return n

    n %= pisano

    fib_arr = [1,1]
    for _ in range(n):
        fib_arr.append((fib_arr[-1] + fib_arr[-2]) % 10)

    return (fib_arr[-1] - 1) % 10

For more information refer to saveriogzz Github CS_Curriculum repo .有关更多信息,请参阅saveriogzz Github CS_Curriculum 存储库

Cheers!干杯!

Here is a simple C++ program这是一个简单的 C++ 程序

//outputs last digit of ( sum of fib number till n)
#include<iostream>
using namespace std;

int64_t fib_sum_digit(int64_t n)
{
    int fl[60] ={0};
    fl[0] = 0;
    fl[1] = 1;
   // int64_t sum60 = 1;

    for(int i = 2 ; i<60 ; i++)
    {
        fl[i] = (fl[i-1] +fl[i-2])%10 ; 
        //sum60 += fl[i]; 
    }


    int64_t sum = 0;
    // sum += (sum60*(n/60));               ///sum60%10 always  = 0 ;

    for(int i = 1; i<=(n%60); i++ )
    {
        sum += (fl[i]);
        //cout<<i<<","<<sum<<"->";         ///debug
    }

return sum%10;
}

int main()
{
    int64_t n;
    cin>>n;

    int64_t ans = fib_sum_digit(n);
    cout<<ans;

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM