利用Redis缓存提高斐波拉契数列程序的性能例子

去某家公司面试,PHP岗位,先做笔试,再两轮面试,最后hr面,拿了offer。

 

笔试题都不难,做完随手拍了一张,然后回去把这道求斐波那契数列的题在电脑上运行了一遍,写的当然是对的,但是当你要求第N位,当N大于60的时候就会非常慢了,后来就想着用Redis缓存来优化性能,效果非常惊人!

 

 

我把题目改了一下,也是要用递归,但是是要列出从0到n的斐波那契数列,并且用Redis缓存。

 

思路很简单,每次取第n的值的时候判断Redis有没有,有就不用再去计算了,没有就计算一次存下来,大大减少计算次数。存的是hash结构。代码如下:

 

在Laravel框架写个控制器方法:

//斐波拉契数列
public function fib($n = null)
{
    if ($n > 100) {
        die('Number must <= 100!');
    }
    for ($i = 0; $i <= $n; $i++) {
        echo $this->getNum($i) . ' ';
    }
}
 
private function getNum($n)
{
    $key = 'com.tanteng.me.test.foo';
    $value = Redis::hget($key, $n);
    if ($value) {
        return $value;
    }
    if ($n == 0) $result = 1;
    if ($n == 1) $result = 1;
    if ($n > 1) {
        $result = $this->getNum($n - 2) + $this->getNum($n - 1);
    }
    Redis::hset($key, $n, $result);
    Redis::expire($key, 1800);
    return $result;
}

在routes.php文件添加路由:

PHP

Route::get('/test/fib/{n?}', ['uses' => 'TestController@fib']);
通过浏览器访问:http://www.111cn.net /test/fib/65

结果很快出来:

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 20365011074 32951280099 53316291173 86267571272 139583862445 225851433717 365435296162 591286729879 956722026041 1548008755920 2504730781961 4052739537881 6557470319842 10610209857723 17167680177565 27777890035288

其中Redis存的内容如下:

 

如果不用Redis,求65个斐波那契数列就会很慢了,使用Redis几乎是刷的一下就出来。在实际开发中,Redis也被广泛使用,Redis真是个好东西

时间: 2024-11-03 20:48:18

利用Redis缓存提高斐波拉契数列程序的性能例子的相关文章

【数学题】斐波拉契数列!

兔子的繁殖能力很强,一对兔子每过一个月会生一对小兔子.而刚出生的一对小兔子经过一个月后长大,再过一个月生出一对小兔子.如果从刚生的一对兔子算起,一年后总共有多少对兔子? 答案:233对.每个月结束时,兔子的对数:1  12  23  34  55  86  137  218  349  5510 8911 14412 233设数列{An}={1,2,3,5,8--}={A1,A2--An-1,An}.则An=An-1+An-2(下标)第n月结束时兔子对数=n-1月兔的对数+新生兔子对数.新生兔对

循环体-求斐波拉契的第n项的值,迭代实现

问题描述 求斐波拉契的第n项的值,迭代实现 实现代码如下(利用迭代): long diedai(int n) { long result; long p_result; long n_result; result=p_result=1; //这一段表达的斐波拉契数列第n项的值 while(n>2) { n-=1; n_result=p_result;//把前一项的值赋给前一项的前一项 p_result=result; // result=p_result+n_result;//结果等于前一项加上

基础-斐波那契数列 利用循环输出前40项 (初学者)

问题描述 斐波那契数列 利用循环输出前40项 (初学者) 我在查了资料之后找到以下解决方法: #include int main() { long fib[41] = {0,1}; int i; for (i=2;i<41;i++) fib[i] = fib[i-1]+fib[i-2]; for (i=1;i<41;i++) printf("F%d==%dn",i,fib[i]); getch(); return 0; } 有些看不懂,希望可以帮我详细分析一下运算过程,或者

HDOJ/HDU 1865 1sting(斐波拉契+大数~)

Problem Description You will be given a string which only contains '1'; You can merge two adjacent '1' to be '2', or leave the '1' there. Surly, you may get many different results. For example, given 1111 , you can get 1111, 121, 112,211,22. Now, you

HDOJ/HDU 5686 Problem B(斐波拉契+大数~)

Problem Description 度熊面前有一个全是由1构成的字符串,被称为全1序列.你可以合并任意相邻的两个1,从而形成一个新的序列.对于给定的一个全1序列,请计算根据以上方法,可以构成多少种不同的序列. Input 这里包括多组测试数据,每组测试数据包含一个正整数N,代表全1序列的长度. 1≤N≤200 Output 对于每组测试数据,输出一个整数,代表由题目中所给定的全1序列所能形成的新序列的数量. Sample Input 1 3 5 Sample Output 1 3 8 Hin

算法-斐波那契数列的性能优化

问题描述 斐波那契数列的性能优化 10C http://www.nowcoder.com/books/coding-interviews/c6c7742f5ba7442aada113136ddea0c3?rp=1 牛客网上 的这道题,一个简单的递归,性能不满足要求,请问 有什么提高性能的算法 解决方案 递归性能当然差了,解决档案是:将递归改为迭代! 解决方案二: 为啥不直接上通项公式 解决方案三: 这是我写的源代码.接下来我将对递归和迭代进行分析,我觉得这才是重点! 解决方案四: 在大部分情况下

斐波那契数列和反向计算问题

反向计算:编写一个函数将一个整型转换为二进制形式 反向计算问题,递归比循环更简单 分析:需要理解,奇数的二进制最后一位是1,偶数的二进制最后一位一定是0,联想记忆,这个和整型的奇偶性是一致的,1本身就是奇数,0本身是偶数.     十进制整数转换为二进制整数采用"除2取余,逆序排列"法. 具体做法是:用2整除十进制整数,可以得到一个商和余数,再用2去除商,又会得到一个商和余数,如此进行,直到商为0时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,

内存管理-根据题目,编这个程序怎么会联想到用斐波那契数列?

问题描述 根据题目,编这个程序怎么会联想到用斐波那契数列? 4.编写-个函数,它返回函数自身被调用的次数,并在一个循环中测试之. #include int Fibonacci(int n); int count; int main(void) { int n; printf("input the max term of Fibonacci:"); while( scanf("%d",&n) == 1 ) { count = 0; Fibonacci(n);

递归解决斐波那契数列

1.什么是递归? 递归:递归是方法定义调用方法本身的现象.递归举例如下: <span style="font-size:14px;">public class DiGuiDemo { //递归方法举例 public void show() { show(); } } </span> 2.递归的注意事项? (1)递归一定要有出口.否则就会死递归. 上面举例用的递归就是一个死递归,方法永远都在进行自身调用,最终一定会陷入内存崩溃.所以递归要定义出口,就是结束递归的条