C++:表达式的计算

一、后缀表达式的计算

#include<bits/c++.h>
using namespace std;

// 后缀表达式的计算

int main()
{
    stack<int> s;
    char cal[1000];
    
    cout << "输入后缀表达式:";
    cin >> cal;
    
    for (int i = 0; i < strlen(cal); i++)
    {
        if (cal[i] - '0' >= 0 && '9' - cal[i] >= 0)
        {
            s.push(cal[i] - '0');
        }    
        else
        {
            if (cal[i] == '+')
            {
                int back = s.top();
                s.pop(); 
                int front = s.top();
                s.pop();
                int result = front + back;
                s.push(result);
            }
            else if (cal[i] == '-')
            {
                int back = s.top();
                s.pop(); 
                int front = s.top();
                s.pop();
                int result = front - back;
                s.push(result);
            }
            else if (cal[i] == '*')
            {
                int back = s.top();
                s.pop(); 
                int front = s.top();
                s.pop();
                int result = front * back;
                s.push(result);
            }
            else if (cal[i] == '/')
            {
                int back = s.top();
                s.pop(); 
                int front = s.top();
                s.pop();
                int result = front / back;
                s.push(result);
            }
            else if (cal[i] == '%')
            {
                int back = s.top();
                s.pop(); 
                int front = s.top();
                s.pop();
                int result = front % back;
                s.push(result);
            }
        }
    }
    
    cout << "后缀表达式计算结果是:" << s.top() << endl;

        
    return 0;
}

/*
测试
234+*82/-
*/

二、中缀表达式的计算

需要一个操作数栈和一个运算符栈

定义计算操作

计算操作:操作数栈弹栈两次,运算符栈弹栈一次,进行相应的计算

扫描中缀表达式时遵循以下规则

  • 若扫描到操作数,直接进操作数栈,并继续扫描

  • 若扫描到运算符为 ( 、 * 、 /,直接进运算符栈,并继续扫描

  • 若扫描到运算符为 ) ,若栈顶运算符为+ 、- 、* 、/ ,进行计算操作,直至栈顶运算符为 ( ,停止计算,并运算符栈弹栈一次,继续扫描

  • 若扫描到运算符为+ 、- ,若运算符栈为空,直接进栈并继续扫描;若运算符栈顶为+ 、- 、( 直接进栈并继续扫描;若栈顶运算符为* 、/ ,进行计算操作,直至栈顶运算符不为* 、/,再将+ 、- 进栈并继续扫描

中缀表达式扫描完成以后

  • 若运算符栈为空,则中缀表达式的值则为操作数栈的栈顶元素

  • 若运算符栈不为空,进行计算操作,直至运算符栈为空,此时中缀表达式的值为操作数栈的栈顶元素

#include<bits/stdc++.h>
using namespace std;

// 中缀表达式的计算
// 以下代码仅适用于操作数为一位整数的情况

int main()
{
    stack<int> snum;
    stack<char> sop;
    char cal[1000];
    
    cout << "输入中缀表达式:";
    cin >> cal;
    
    for (int i = 0; i < strlen(cal); i++)
    {
        if (cal[i] - '0' >= 0 && '9'- cal[i] >= 0)
        {
            snum.push(cal[i] - '0');
        }
        else
        {
            if (cal[i] == '(')
            {
                sop.push(cal[i]);
            }
            else if (cal[i] == ')')
            {    
                while(sop.top() != '(')
                {
                    int num2 = snum.top();
                    snum.pop();
                    int num1 = snum.top();
                    snum.pop();
                    char op = sop.top();
                    sop.pop();
                    if (op == '+')
                    {
                        int num3 = num1 + num2;
                        snum.push(num3);    
                    }
                    else if (op == '-')
                    {
                        int num3 = num1 - num2;
                        snum.push(num3);
                    }
                    else if (op == '*')
                    {
                        int num3 = num1 * num2;
                        snum.push(num3);
                    }
                    else if (op == '/')
                    {
                        int num3 = num1 / num2;
                        snum.push(num3);
                    }
                }
                sop.pop();
            }
            else if (cal[i] == '+' || cal[i] == '-')
            {
                if (!sop.empty())
                {
                    while(sop.top() == '*' || sop.top() == '/')
                    {
                        int num2 = snum.top();
                        snum.pop();
                        int num1 = snum.top();
                        snum.pop();
                        char op = sop.top();
                        sop.pop();
                        if (op == '*')
                        {
                            int num3 = num1 * num2;
                            snum.push(num3);    
                        }
                        else if (op == '/')
                        {
                            int num3 = num1 / num2;
                            snum.push(num3);
                        }
                        if (sop.empty() || sop.top() == '(')
                            break;
                    }
                    sop.push(cal[i]);
                }
                else
                {
                    sop.push(cal[i]);
                }
            }
            else if (cal[i] == '*' || cal[i] == '/')
            {
                sop.push(cal[i]);
            }
        }
    }
    
    while(!sop.empty())
    {
        int num2 = snum.top();
        snum.pop();
        int num1 = snum.top();
        snum.pop();
        char op = sop.top();
        sop.pop();
        if (op == '+')
        {
            int num3 = num1 + num2;
            snum.push(num3);    
        }
        else if (op == '-')
        {
            int num3 = num1 - num2;
            snum.push(num3);
        }
        else if (op == '*')
        {
            int num3 = num1 * num2;
            snum.push(num3);
        }
        else if (op == '/')
        {
            int num3 = num1 / num2;
            snum.push(num3);
        }
    }
    
    cout << "中缀表达式计算结果是:" << snum.top() << endl;
        
    return 0;
}
/*
测试
2*(3+4)-8/2

(8*1+7*2)+(8/1-6/2)
*/

三、中缀表达式转换后缀表达式

中缀表达式转后缀表达式与中缀表达式的计算操作基本相同

只需要使用一个存储运算符的栈,操作数直接加入结果表达式中

运算符出栈的规律与计算时相同,但不用进行计算,只需要将出栈的运算符添加到表达式末尾

#include<bits/stdc++.h>
using namespace std;
 
// 中缀表达式转后缀表达式
// 以下代码仅适用于操作数为一位整数的表达式
 
int main()
{
    stack<char> sop;
    char cal[1000];
    
    cout << "输入中缀表达式:";
    cin >> cal;
    
    char back[1000];
    int index = 0;
    
    for (int i = 0; i < strlen(cal); i++)
    {
        if (cal[i] - '0' >= 0 && '9'- cal[i] >= 0)
        {
            back[index++] = cal[i];
        }
        else
        {
            // 若扫描到 (
            if (cal[i] == '(')
            {    
                sop.push(cal[i]);
            }
            // 若扫描到 * 或 /
            else if (cal[i] == '*' || cal[i] == '/')
            {    
                if (!sop.empty())
                {
                    if (sop.top() == '*' || sop.top() == '/')
                    {
                        back[index++] = sop.top();
                        sop.pop();
                    }
                }
                sop.push(cal[i]);
            }
            // 若扫描到 )
            else if (cal[i] == ')')
            {    
                while(sop.top() != '(')
                {
                    char op = sop.top();
                    sop.pop();
                    if (op == '+')
                    {
                        back[index++] = '+';    
                    }
                    else if (op == '-')
                    {
                        back[index++] = '-';
                    }
                    else if (op == '*')
                    {
                        back[index++] = '*';
                    }
                    else if (op == '/')
                    {
                        back[index++] = '/';
                    }
                }
                sop.pop();
            }
            // 若扫描到 + 或 -
            else if (cal[i] == '+' || cal[i] == '-')
            {
                if (!sop.empty())
                {
                    while(sop.top() == '*' || sop.top() == '/')
                    {
                        char op = sop.top();
                        sop.pop();
                        if (op == '*')
                        {
                            back[index++] = '*';    
                        }
                        else if (op == '/')
                        {
                            back[index++] = '/';
                        }
                        if (sop.empty() || sop.top() == '(')
                            break;
                    }
                    if (!sop.empty())
                    {
                        if (sop.top() == '+' || sop.top() == '-')
                        {
                            back[index++] = sop.top();
                            sop.pop();
                        }
                    }
                    sop.push(cal[i]);
                }
                else
                {
                    sop.push(cal[i]);
                }
            }
        }
    }
    
    while(!sop.empty())
    {
        char op = sop.top();
        sop.pop();
        if (op == '+')
        {
            back[index++] = '+';
        }
        else if (op == '-')
        {
            back[index++] = '-';
        }
        else if (op == '*')
        {
            back[index++] = '*';
        }
        else if (op == '/')
        {
            back[index++] = '/';
        }
    }
    
    cout << "转换成后缀表达式为:" << back << endl;
        
    return 0;
}
/*
测试
2*(3+4)-8/2
(8*1+7*2)+(8/1-6/2)
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值