背包
下面一个例子是计算标准输入中的所有double
值的平均数和样本标准差。
#include <iostream>
#include <cmath>
#include "bag.h"
int main()
{
Bag<double> bag;
double d;
while (std::cin >> d) {
bag.Add(d);
}
double sum = 0;
for (auto x : bag) {
sum += x;
}
double mean = sum / bag.Size();
sum = 0;
for (auto x : bag) {
sum += (x - mean) * (x - mean);
}
double std = sqrt(sum / (bag.Size() - 1));
std::cout << mean << std::endl;
std::cout << std << std::endl;
return 0;
}
为了能使用范围for语句遍历bag
对象中的元素,需要给背包加上begin()
和end()
方法(deque
的迭代器支持++
操作)。
template <typename Item>
class Bag {
public:
typename std::deque<Item>::iterator begin();
typename std::deque<Item>::iterator end();
// ...
};
template <typename Item>
typename std::deque<Item>::iterator Bag<Item>::begin()
{
return dq_.begin();
}
template <typename Item>
typename std::deque<Item>::iterator Bag<Item>::end()
{
return dq_.end();
}
运行结果(命令行中ctrl + D
是EOF
):
队列
下面一个例子是把标准输入的int
值按顺序存储到一个数组里,我们预先并不知道该为数组分配多少内存。
#include <iostream>
#include <cmath>
#include "queue.h"
int main()
{
Queue<int> qi;
int ele;
while (std::cin >> ele) {
qi.EnQueue(ele);
}
int N = qi.Size();
int arr[N];
for (int i = 0; i < N; ++i) {
arr[i] = qi.Dequeue();
}
for (int i = 0; i < N; ++i) {
std::cout << arr[i] << std::endl;
}
return 0;
}
运行结果(D
是命令行输入EOF
出现的):
栈
在下面的例子中,把标准输入中的整数按逆序打印出来。
#include <iostream>
#include "stack.h"
int main()
{
Stack<int> si;
int ele;
while (std::cin >> ele) {
si.Push(ele);
}
while (!si.IsEmpty()) {
std::cout << si.Pop() << std::endl;
}
return 0;
}
运行结果:
算术表达式求值
栈的一个经典用例是计算算术表达式:输入一个字符串,输出一个值。
为了简单起见,表达式不省略括号(使用括号而非优先级规则做四则运算),括号、操作数、运算符之间用空格隔开。
输入:( 1 + ( 2 + 3 ) * ( 4 * 5 ) )
输出:101
E.W.Dijkstra
在20
世纪60
年代发明了一种非常简单的算法,过程如下:
(1)
准备两个栈:操作数栈和运算符栈。
(2)
遍历算术表达式。
(3)
将操作数压入操作数栈、运算符压入运算符栈,忽略左括号。
(4)
遇到右括号时,弹出一个运算符,再弹出所需的操作数,执行运算,把结果压入操作数栈。
(5)
处理完最后一个右括号时,操作数栈上只会有一个值,那便是表达式的结果。
代码实现:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cmath>
#include "stack.h"
using std::string;
void Calculate(Stack<string> &ops, Stack<double> &vals)
{
string op = ops.Pop();
double a = vals.Pop();
if (op == string("+")) {
double b = vals.Pop();
vals.Push(a + b);
} else if (op == string("-")) {
double b = vals.Pop();
vals.Push(b - a);
} else if (op == string("*")) {
double b = vals.Pop();
vals.Push(a * b);
} else if (op == string("/")) {
double b = vals.Pop();
vals.Push(b / a);
} else if (op == string("sqrt")) {
vals.Push(sqrt(a));
} else {
std::cout << "unknown operator" << std::endl;
}
}
int main()
{
Stack<string> ops; // 运算符栈
Stack<double> vals; // 操作数栈
string str;
while (std::cin >> str) {
if (str == string("(")) {
continue;
} else if ((str == string("+")) || (str == string("-")) ||
(str == string("*")) || (str == string("/")) ||
(str == string("sqrt"))) {
ops.Push(str);
continue;
} else if (str == string(")")) {
Calculate(ops, vals);
} else {
vals.Push(atof(str.c_str()));
}
}
std::cout << vals.Pop() << std::endl;
return 0;
}
运行结果:
该实现未提供参数检查机制。