背包、队列和栈的典型用例

背包

下面一个例子是计算标准输入中的所有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 + DEOF):
在这里插入图片描述

队列

下面一个例子是把标准输入的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.Dijkstra20世纪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;
}

运行结果:
在这里插入图片描述

该实现未提供参数检查机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值