栈实现表达式求值

通过前两天的博客园,可以知道我最近在疯狂补作业,这是我在数据结构实验课遇到的一个题,我通过搜寻相关知识点,理清了后缀表达式的转化过程

题目要求:

使用键盘输入数学表达式(含数字,四种运算符+、-、、/和小括号,其中运算数都是一位数(0~9)),将数学表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。

输入格式:

输入正确的表达式(可以有空格)后回车,得到后缀表达式和结果。输入括号缺失的表达式,输出"ERROR:缺少括号"。输入两个除括号外运算符连续的表达式,输出"ERROR:表达式缺操作数"。

输出格式:

请在这里描述输出格式。例如:对每一组输入,在一行中输出A+B的值。

输入样例:

在这里给出一组输入。例如:

5*(8-(3+2))

输出样例:

在这里给出相应的输出。例如:

5832+-
15

源码如下
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
const int N = 100010;
string change(string s) 
{
    string ss;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == 32) continue;//空格继续输入
        ss += char(s[i]);//强制转换为字符类型
    }
    return ss;
}

bool ck1(string s) //判断字符串是否缺少对应的括号
{
    int cnt = 0;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == '(') cnt++;
        else if (s[i] == ')') cnt--;
    }
    return  cnt == 0;
}

bool ck2(string s) //判断字符串是否符合运算规律
{
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
            if (i == 0 || i == s.size() - 1 || i && (s[i - 1] == '+' || s[i - 1] == '-' || s[i - 1] == '*' || s[i - 1] == '/')) {
                return 0;
            }
        }
    }
    return 1;
}

int cx(char ch) 
{ 
    return ch == '*' || ch == '/' ? 2 : 1; 
}
char ch[N];
int cnt;
string cg(string s) {
    string ss;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] >= '0' && s[i] <= '9') {
            ss += char(s[i]);
        }
        else {
            if (s[i] == '(') {
                ch[cnt++] = '(';
            }
            else if (s[i] == ')') {
                while (ch[cnt - 1] != '(') {
                    ss += ch[--cnt];
                }
                cnt--;
            }
            else {
                char c = char(s[i]);
                if (cnt > 0 && cx(c) <= cx(ch[cnt - 1])) {
                    while (cnt > 0 && ch[cnt - 1] != '(' && cx(c) <= cx(ch[cnt - 1])) {
                        ss += ch[--cnt];
                    }
                }
                ch[cnt++] = c;
            }
        }
    }
    while (cnt > 0) {
        ss += ch[--cnt];
    }
    return ss;
}

int op(int x, int y, char ch) {
    if (ch == '+') return x + y;
    else if (ch == '-') return x - y;
    else if (ch == '*') return x * y;
    else return x / y;
}
int a[N], ct=0;
int op(string s) {
    for (int i = 0; i < s.size(); i++) {
        if (s[i] >= '0' && s[i] <= '9') {
            a[ct++] = s[i] - 48;
        }
        else {
            int x = a[ct - 2], y = a[ct - 1];
            ct -= 2;
            a[ct++] = op(x, y, char(s[i]));
        }
    }
    return a[0];
}

int main() {
    string s;
    getline(cin, s);

    s = change(s);

    if (!ck1(s)) {
        cout << "ERROR:缺少括号";
        return 0;
    }

    if (!ck2(s)) {
        cout << "ERROR:表达式缺操作数";
        return 0;
    }

    string ss = cg(s);
    cout << ss << endl;

    cout << op(ss);

    return 0;
}

 

实验体会
在实验过程中,我先观看了老师的讲解视频,在视频中我有了一个大概的思路,在进行编写的时候,我对于如何转变为中缀式和后缀式有些疑问,对于符号和位置的表达不够清晰,后来我在网上查找了一些资料,了解到了中缀式和后缀式的转化,最终成功实现了本次实验。经过本次实验,关于表达式求值,用栈的方式,首先判断输入的数字和符号,以此判断优先级,在整个运算过程中括号的优先级最高,依次是乘除和加减,通过函数cg,将数字单独安顺序输入数组是s[i],括号运算符输入数组ch[],并且记录下运算符的位置,然后专门计算括号内的算术式,设置函数op计算四个运算符,设置函数判断输入括号缺失的表达式,输出"ERROR:缺少括号"。输入两个除括号外运算符连续的表达式,输出"ERROR:表达式缺操作数"。在本次实验中,我进行了栈的练习,学习了如何利用栈进行对于带括号的运算式的计算,如何将运算式变成中缀式,再从中缀式变成后缀式,对于栈有了更深的了解,但还是对知识点的掌握有很大的不足,需要继续练习和复习栈知识。
posted @ 2022-11-30 22:57  伽澄  阅读(172)  评论(0编辑  收藏  举报