机试_3_数据结构(一)_习题

数据结构(一)——练习题

学习完第三章-数据结构(一)之后,当然要做相应地练习啦~

注:上述习题都可以在牛客进行测试。

例如,第2题链接:计算表达式_牛客题霸_牛客网 (nowcoder.com),其他题目在“题目列表”中基本都可以找到。

另外,此文章仅仅是提供解题思路,并非最优解。


1、堆栈的使用–吉林大学

描述

堆栈是一种基本的数据结构。堆栈具有两种基本操作方式,push 和 pop。其中 push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。(注:本题有多组输入,可以参考该网址:https://www.nowcoder.com/discuss/276)

输入描述:

对于每组测试数据,第一行是一个正整数 n(0 < n <= 10000)。而后的 n 行,每行的第一个字符可能是’P’或者’O’或者’A’;如果是’P’,后面还会跟着一个整数,表示把这个数据压入堆栈;如果是’O’,表示将栈顶的值 pop 出来,如果堆栈中没有元素时,忽略本次操作;如果是’A’,表示询问当前栈顶的值,如果当时栈为空,则输出’E’。堆栈开始为空。

输出描述:

对于每组测试数据,根据其中的命令字符来处理堆栈;并对所有的’A’操作,输出当时栈顶的值,每个占据一行,如果当时栈为空,则输出’E’。

示例1

输入:

3
A
P 5
A
4
P 3
P 6
O
A

输出:

E
5
3

题解:

#include <iostream>
#include <cstdio>
#include <stack>

using namespace std;

/**
 * 堆栈的使用
 * @return
 */
int main() {
    int n;
    while (cin >> n) {
        stack<int> stack;
        for (int i = 0; i < n; ++i) {
            char instruction;
            cin >> instruction;
            if (instruction == 'P') {
                int num;
                cin >> num;
                stack.push(num);
            } else if (instruction == 'O') {
                if (!stack.empty()) {
                    stack.pop();
                }
            } else {
                if (stack.empty()) {
                    cout << "E" << endl;
                } else {
                    cout << stack.top() << endl;
                }
            }
        }
    }
    return 0;
}


2、计算表达式–上海交通大学

描述

对于一个不存在括号的表达式进行计算

输入描述:

存在多组数据,每组数据一行,表达式不存在空格

输出描述:

输出结果

示例1

输入:

6/2+3+3*4

输出:

18

题解:

解题:
1. 在表达式的结尾加上"#",表示结束符,然后从左到右遍历计算式
2. 若为操作数num,则压入操作数栈中
3. 若为运算符,则依次弹出运算符栈中比当前运算符优先级高的运算符;
   同时,依次弹出操作数栈中的元素(注意:先弹出的为右操作数)
   然后,执行相应的计算,将计算结果压入到操作数栈中。
   最后,将当前的运算符压入到运算符栈中。
4. 若为结束符"#",依次弹出运算符栈中的运算符,依次弹出操作数栈中的元素,执行计算后将结果压入栈中
5. 最后栈中只剩一个元素,即为计算结果。
#include <iostream>
#include <cstdio>
#include <stack>
#include <string>
#include <map>

using namespace std;

/**
 * 计算运算符的操作结果
 * @param opera 运算符
 * @param leftNum 左操作数
 * @param rightNum 右操作数
 * @return
 */
double calculate(char opera, double leftNum, double rightNum);

/*
 * map存放运算符的优先级
 */
map<char, int> priority = {
        {'$', 0},
        {'+', 1},
        {'-', 1},
        {'*', 2},
        {'/', 2}
};

/**
 * 计算表达式--上海交通大学
 * @return
 */
int main() {
    string str;
    while (cin >> str) {
        /*
         * 给表达式加上结束符
         */
        str += "#";
        stack<char> operaStack;
        stack<double> numStack;
        string num = "";
        for (int i = 0; i < str.size(); ++i) {
            char cur = str[i];
            if (cur == '#') {
                /*
                 * 结束符
                 * 1. 先将结束符#前面的num压入操作数栈中
                 * 2. 依次弹出运算符栈中的运算符
                 * 3. 依次弹出操作数栈中的操作符(注:先弹出的是右操作数)
                 * 4. 执行相应计算,再将计算结构压入栈中
                 */
                if (num != "") {
                    numStack.push(stod(num));
                    num = "";
                }
                while (!operaStack.empty()) {
                    char opera = operaStack.top();
                    operaStack.pop();
                    double rightNum = numStack.top();
                    numStack.pop();
                    double leftNum = numStack.top();
                    numStack.pop();
                    numStack.push(calculate(opera, leftNum, rightNum));
                }
            } else if ('0' <= cur && cur <= '9') {
                /*
                 * 0~9,将数字拼接到num中
                 */
                num += cur;
            } else {
                /*
                 * 操作符
                 * 1. 先将操作符前面的num压入操作数栈中
                 * 2. 依次弹出运算符栈中的运算符比当前运算符优先级高的运算符
                 * 3. 依次弹出操作数栈中的操作符(注:先弹出的是右操作数)
                 * 4. 执行相应计算,再将计算结构压入栈中
                 * 5. 将当前的运算符压入运算符栈中
                 */
                if (num != "") {
                    numStack.push(stod(num));
                    num = "";
                }
                while (!operaStack.empty() && priority[operaStack.top()] >= priority[cur]) {
                    char opera = operaStack.top();
                    operaStack.pop();
                    double rightNum = numStack.top();
                    numStack.pop();
                    double leftNum = numStack.top();
                    numStack.pop();
                    numStack.push(calculate(opera, leftNum, rightNum));
                }
                operaStack.push(cur);
            }
        }
        /*
         * 此时,栈中有且只有一个元素,即为计算结果
         */
        cout << numStack.top() << endl;
    }

    return 0;
}

double calculate(char opera, double leftNum, double rightNum) {
    double res = 0;
    switch (opera) {
        case '+':
            res = leftNum + rightNum;
            break;
        case '-':
            res = leftNum - rightNum;
            break;
        case '*':
            res = leftNum * rightNum;
            break;
        case '/':
            res = leftNum / rightNum;
            break;
        default:
            break;
    }
    return res;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

窝在角落里学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值