简介
平时在写代码的时候,有时候看似很简单的代码,但是运行之后,随着数值的增大,电脑的运算能力有限,速度变得极慢,但是由于专业知识不足,无法自己优化代码,只能去网上抄别人已经优化的代码。
现在就教大家如何用数组记忆的方式,优化整个代码的步骤。
例子
菲波纳契数列
以菲波纳契数列为例子,普通代码如下:
int fib(int n)
{
step1++;
if (n <= 1)return n;
return fib(n - 1) + fib(n - 2);
}
简单输入一个40的数字,输出结果和step1
简单的40,需要计算3亿多次,我们先看一下这个原版的菲波纳契数列的计算思维图。
这是一种自上而下的计算方式,看到这个计算思维导图的时候,我们可以发现一个问题,就是在这个整个步骤里面,很多步骤都是重复的,计算f(10)总共计算了
1个f(9)
2个f(8)
3个f(7)
......
当传入的f(n)中的n越来越大时,计算次数的的增加也是很可怕的。
造成这样的原因其实是在这些2个f(8)、3个f(7)......中,有很多重复的步骤,因为计算机只在计算,并没有把这些相同的数字给记录下来,如果创建一个数组,能把之前算过的步骤记录下来,这样就可以省略很多重复的步骤,这样就可以画成这样:
用一个数组记录过去的值,然后依次自下而上的反推出结果。
创建一个数组memo[],把算过一次的结果给记录下来,然后再上一次递归的时候接收到,就不需要再反复的重复多余的步骤。
修改代码后是这样的:
int fib(int n)
{
step2++;
if (n <= 1)return n;
if (memo[n] != 0)return memo[n];
return memo[n] = fib(n - 1) + fib(n - 2);
}
输入40对比结果:
该代码中fib(n-1)总共递归了39次,fib(n-2)总共也递归了39次。当左右两边递归到最底层的时候,随之返回的结果都已经通过数组储存下来,这样只需要一直把结果return回来,上一层的层层接收,就可以完成计算。
结尾
以上只是一个简单的例子,也是动态规划的简单入门。各位可以尝试使用这个方式优化其他的代码,关键在于画出计算思维图片,找出每个数字的关系,找出重复的步骤,创建数组记录下来,这样就可以消除计算冗余,提高代码效率。