2.1.1 递归函数
- 定义:函数调用自身的行为。
- 递归三要素:
- 找到问题的了逻辑相似性
- 找到合适的参数
- 递归的出口
比如斐波那契数列,一般的做法很简单
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
but,计算机白白多消耗了一些时间计算重复的东西。
so,解决办法就是设置一个数组,将F(1)~F(n-1)所有结果存起来【这就是动态规划的思想】
max = 50
temp = [0 for i in range(1, max + 1)]
def fib(n):
if n <= 1:
return n
if temp[n] != 0:
return temp[n]
temp[n] = fib(n - 1) + fib(n - 2)
return temp[n]
完整程序:
/*
斐波那契数列
用递归的思想实现,很简单
但是有很多计算是重复的
考虑到动态规划的思想
将每一次算出来的结果用一个数组存储(记忆)
会减少计算时间
*/
#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_N = 100;
int a[MAX_N];
int f(int n){
if(n<=1) return n;
if(a[n]!=0) return a[n];
return a[n] = f(n-1)+f(n-2);
}
int main(){
int n;
while(1){
cin>>n;
cout<<f(n)<<endl;
memset(a, 0, sizeof(a)); // 循环调用一个公共变量,所以需要清空
}
return 0;
}
2.1.2 栈和队列
栈:FILO 队列:FIFO
简单实现
/*
栈的简单push、pop
队列
*/
#include<iostream>
#include<cstdio>
#include<stack>
#include<queue>
using namespace std;
int main(){
stack<int> s; // 需要声明栈中元素的数据类型
int size = 0;
// queue<int> s;
s.push(1);
s.push(2);
s.push(3);
size = s.size();
for(int i = 0;i<size;i++){
cout<<i<<" "<<s.top()<<endl; // stack中访问最底端数据
// cout<<s.front()<<endl; // queue中访问最底端数据
s.pop();
}
return 0;
}
/*
随着元素被pop出stack或queue,size也在减小,所以才不能弹出所有的元素
所以,s.size()要在循环之前提前赋值给一个变量,而不能直接作为for循环的判断依据,所以,我增加了size变量
*/
没有封装好的栈和队列,所以可以使用list来代替。
一个属于类而非属于对象的方法。这就意味着我们可以将它定义为一个classmethod(类方法) 或是一个 staticmethod(静态方法) ,这取决于我们是否知道我们需不需要知道我们属于哪个类。
class Stack:
count = 0 # 类变量,用类名Stack调用
def __init__(self):
self.values = []
Stack.count += 1 # 可以记录创建对象的数目
def push(self, value): # value作为对象变量,用对象来调用
self.values.append(value)