算法
解决一个问题时,要注意:理解和定义问题,控制问题的复杂度,将其分解为更容易解决的子问题。
解决问题的步骤叫做算法。
在计算机科学领域,我们用算法这个词来描述一种有限、确定、有效的并适合用于计算机程序来实现的解决问题的方法。
计算机的计算和存储资源是有限的,所以只能解决部分的数学理论问题。
要定义一个算法,我们可以用自然语言描述解决某个问题的过程,或着使用某个程序设计语言来实现这个过程。
以计算两个非负整数p
和q
的最大公约数为例。
自然语言描述
若q
是0
,则最大公约数是p
;
否则,将p
除以q
得到余数r
,p
和q
的最大公约数即q
和r
的最大公约数。
C++实现
int gcd(int p, int q)
{
if (q == 0) {
return p;
}
return gcd(q, p % q);
}
相比于自然语言,程序是对算法更精确和完全的描述。
同时,数据结构是算法的副产品或结果,因此要理解算法必须学习数据结构。
数据结构
这里介绍三种数据结构:背包、队列和栈。
泛型和迭代(template<typename Item>
Iterable<Item>
)可以保证三种数据结构能存储任意类型的元素,且元素是以一种可被遍历的形式的保存的。
本例中,使用STL
中的deque
存储元素。背包、队列和栈均是对deque
的封装。
背包
背包是一种收集元素的数据结构,不支持删除元素。
bag.h
#include <deque>
template <typename Item>
class Bag {
public:
Bag(); // 创建空背包
void Add(const Item &item); // 添加元素
bool IsEmpty(); // 背包是否为空
int Size(); // 背包中的元素数量
private:
std::deque<Item> dq_;
};
template <typename Item>
Bag<Item>::Bag() {}
template<typename Item>
void Bag<Item>::Add(const Item &item)
{
dq_.push_back(item);
}
template <typename Item>
bool Bag<Item>::IsEmpty()
{
return dq_.empty();
}
template <typename Item>
int Bag<Item>::Size()
{
return dq_.size();
}
队列
队列是一种基于先进先出策略的集合类型。
queue.h
#include <deque>
template <typename Item>
class Queue {
public:
Queue(); // 创建空队列
void EnQueue(const Item &item); // 添加元素
Item Dequeue(); // 删除最早添加的元素
bool IsEmpty(); // 队列是否为空
int Size(); // 队列中的元素数量
private:
std::deque<Item> dq_;
};
template <typename Item>
Queue<Item>::Queue() {}
template <typename Item>
void Queue<Item>::EnQueue(const Item &item)
{
dq_.push_back(item);
}
template <typename Item>
Item Queue<Item>::Dequeue()
{
auto item = dq_.front();
dq_.pop_front();
return item;
}
template <typename Item>
bool Queue<Item>::IsEmpty()
{
return dq_.empty();
}
template <typename Item>
int Queue<Item>::Size()
{
return dq_.size();
}
栈
栈是一种基于后进先出策略的集合类型。
stack.h
#include <deque>
template <typename Item>
class Stack {
public:
Stack(); // 创建空栈
void Push(const Item &item); // 添加元素
Item Pop(); // 删除最近添加的元素
bool IsEmpty(); // 栈是否为空
int Size(); // 栈中元素的数量
private:
std::deque<Item> dq_;
};
template <typename Item>
Stack<Item>::Stack() {}
template <typename Item>
void Stack<Item>::Push(const Item &item)
{
dq_.push_back(item);
}
template <typename Item>
Item Stack<Item>::Pop()
{
auto item = dq_.back();
dq_.pop_back();
return item;
}
template <typename Item>
bool Stack<Item>::IsEmpty()
{
return dq_.empty();
}
template <typename Item>
int Stack<Item>::Size()
{
return dq_.size();
}
栈的一个经典应用是计算算术表达式的值。例如:
(1 + ((2 + 3) * (4 * 5)))