【挑战程序设计竞赛(第二版)】2.1【递归、栈、队列、DFS、BFS、枚举、剪枝】

2.1.1 递归函数

  1. 定义:函数调用自身的行为。
  2. 递归三要素
    - 找到问题的了逻辑相似性
    - 找到合适的参数
    - 递归的出口

比如斐波那契数列,一般的做法很简单

   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)

    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值