c++表达式求值(利用数据结构栈)

最近在带大二助教,以前上课听得模模糊糊的知识点现在自己动手全部弄明白了!
这里写图片描述
思路:主要是用到栈先进后出的数据结构。在该程序中建有两个栈:一个用于存储运算符OPTR(+-*/#),另一个OPND用于存储操作数或运算结果(5 2 2.5)。基本过程是:
(1)首先设置操作数栈为空栈,设置运算符栈以‘#’为栈底元素(其优先级最低)。
(2)通过为栈内栈外运算符设置值而比较其优先级
(3)依次找到表达式中的所有运算符和操作数,对于操作数直接入栈,运算符则和运算符栈的栈顶运算符进行比较优先级,若栈内优先级大,则进行相应操作并且操作数和栈内运算符都出栈,若优先级相等只需栈内运算符出栈继续查找下一个运算符即可,若栈内优先级低则栈外运算符入栈。依次循环知道分析完表达式中
的所有运算符和操作数即可。
(4)最后在操作数栈中将只会剩下唯一的一个元素,而该元素也将就会是所求表达式的值。

#include<iostream>
#include<stack>
#include<string>
using namespace std;

/*判断符号间的优先关系函数
*1表示>,0表示=,-1表示<
*c1栈内的算符,c2栈外的算符
*/
int Judge(char c1, char c2)
{
    int a1, a2;
    if ('+' == c1 || '-' == c1) a1 = 3;
    if ('*' == c1 || '/' == c1)a1 = 5;
    if ('(' == c1) a1 = 1;
    if (')' == c1) a1 = 7;
    if ('#' == c1) a1 = 0;

    if ('+' == c2 || '-' == c2)a2 = 2;
    if ('*' == c2 || '/' == c2)a2 = 4;
    if ('(' == c2) a2 = 6;
    if (')' == c2) a2 = 1;
    if ('#' == c2) a2 = 0;
    if (a1>a2) return 1;
    if (a1 == a2) return 0;
    if (a1<a2) return -1;
}
//符号运算函数
double run(char c, double d1, double d2)
{
    switch (c)
    {
    case '+':
        return d1 + d2;
        break;
    case '-':
        return d1 - d2;
        break;
    case'*':
        return d1*d2;
        break;
    case '/':
        return d1 / d2;
        break;
    default:
        return 0.0;
        break;
    }
}
int main()
{
    char * op = "+-*/()#";
    string str;
    cin >> str;
    //给表达式字符串str添加'#'结束标识符
    str.append(1, '#');//添加1个#
    stack<char> OPTR;//运算符栈
    stack<double> OPND;//操作数栈
    //a记录操作符位置
    int a = -1;
    //先将#符号入栈
    OPTR.push('#');
    while (true)
    {
        int b = a + 1;
        a = str.find_first_of(op, a + 1);//int find_first_of(char c, int start)查找字符串中第1个出现的c,由位置start开始。
        if (a == string::npos) break;//npos 是一个常数,用来表示不存在的位置
        if (a != b)
        {
            string ss(str, b, a - b);//将字符串str内“始于b且长度顶多a - b”的部分作为字符串的初值
            double d = atof(ss.c_str());//atof 是ascII to float的缩写,将ascII字符串转换为相应的单精度浮点数
            //数据先入栈
            OPND.push(d);
        }
        //运算符优先级比较
        int ju = Judge(OPTR.top(), str[a]);
        if (-1 == ju)//栈外优先级大直接入栈
        {
            OPTR.push(str[a]);
        }
        if (0 == ju)//栈内外优先级相等则出栈
        {
            OPTR.pop();
        }
        if (1 == ju)//栈内优先级大,出栈进行运算
        {
            double d1 = OPND.top();
            OPND.pop();
            double d2 = OPND.top();
            OPND.pop();
            d1 = run(OPTR.top(), d2, d1);
            //运算结果入栈
            OPND.push(d1);
            OPTR.pop();
            a--;
        }
    }
    //删除表达式最后的'#'结束标识符
    str.erase(str.length() - 1, 1);//erase(pos,n);删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
    cout << str << " = " << OPND.top() << endl;
}
  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值