使用栈求 中缀/后缀/前缀 表达式的代码


类比我的上一篇文章, 前缀/中缀/后缀----表达式之间的相互转换

使用栈求中缀表达式的值的方法:

将数字存入一栈, 运算符存入另一栈. 入栈的运算符必须大于栈顶运算符的优先级才能入栈, 小于等于均将栈顶运算符出栈后计算处理. 如图作a(值为4)*=b(值为5)从而得到a的值为20. 左括号类比栈底处理, 右括号类比原数组循环结束后, 排空运算符堆栈的操作.
在这里插入图片描述
实现代码如下(参考天勤代码):

#include <iostream>
#include <cmath>
using namespace std;

const int maxSize = 14;
const float Min = 1e-3;

int getPriority(char op)
{
    switch (op)
    {
    case '+':
    case '-':
        return 0;
    case '*':
    case '/':
        return 1;
    }
}

int calSub(float num1, char op, float num2, float &result)
{
    switch (op)
    {
    case '/':
        if (fabs(num2) < Min)
            return 0;
        else
            result = num1 / num2;
        break;
    case '*':
        result = num1 * num2;
        break;
    case '+':
        result = num1 + num2;
        break;
    case '-':
        result = num1 - num2;
    }
    return 1;
}

int calTopTwo(float s1[], int &top1, char s2[], int &top2)
{
    float num1, num2, result;
    num2 = s1[top1--];
    num1 = s1[top1--];
    char op = s2[top2--];
    int flag = calSub(num1, op, num2, result);
    if (flag == 0)
    {
        cout << "Error";
    }
    s1[++top1] = result;
    return flag;
}

float calInfix(char exp[])
{
    float s1[maxSize];
    int top1 = -1;
    char s2[maxSize];
    int top2 = -1;
    int i = 0;
    while (exp[i] != '\0')
    {
        if ('0' <= exp[i] && exp[i] <= '9')
        {
            s1[++top1] = exp[i] - '0';
            i++;
        }
        else if (exp[i] == '(')
        {
            s2[++top2] = '(';
            i++;
        }
        else if (exp[i] == '+' ||
                 exp[i] == '-' ||
                 exp[i] == '*' ||
                 exp[i] == '/')
        {
            if (top2 == -1 ||
                s2[top2] == '(' ||
                getPriority(exp[i]) > getPriority(s2[top2]))
            {
                s2[++top2] = exp[i];
                i++;
            }
            else
            {
                int flag = calTopTwo(s1, top1, s2, top2);
                if (flag == 0)
                    return 0;
            }
        }
        else if (exp[i] == ')')
        {
            while (s2[top2] != '(')
            {
                int flag = calTopTwo(s1, top1, s2, top2);
                if (flag == 0)
                    return 0;
            }
            i++;
            top2--;
        }
    }
    while (top2 != -1)
    {
        int flag = calTopTwo(s1, top1, s2, top2);
        if (flag == 0)
            return 0;
    }
    return s1[0];
}
int main()
{
    char s1[14] = "1+2/4*(3+5*6)";
    cout << calInfix(s1) << endl;
    return 0;
}
/*结果
17.5
*/

使用栈求后缀表达式的方法

将数字和运算符均依次存入栈中, 在压入运算符时, 将栈顶两数字与运算符进行运算, 得到新数字并存回栈中(注意运算次序, 先入栈的在左, 栈顶在右). 具体过程参考此处
代码如下(自己写的野生代码):

#include <iostream>
using namespace std;
const int maxSize = 16;
const float Min = 1e-8;
float calPostFix(char exp[])
{
    float s[maxSize];
    int top = -1, i = 0;
    while (exp[i] != '\0')
    {
        if ('0' <= exp[i] && exp[i] <= '9')
        {
            s[++top] = exp[i++]-'0';
        }
        else
        {
            switch (exp[i++])
            {
            case '+':
                s[--top] += s[top];
                break;
            case '-':
                s[--top] -= s[top];
                break;
            case '*':
                s[--top] *= s[top];
                break;
            case '/':
                if (s[top] < Min)
                {
                    cout << "Error";
                    return 0;
                }
                s[--top] /= s[top];
            }
        }
    }
    return s[0];
}
int main()
{
    char s[maxSize] = {'1', '2', '+', '5', '*'};
    cout << calPostFix(s);
}
/*结果
15
*/

使用栈求前缀表达式的方法

此处求前缀表达式和后缀表达式的方法相似. 此处从右到左扫描, 在栈顶两数字顺序是先入栈在右, 栈顶在左

#include <iostream>
using namespace std;
const int maxSize = 16;
const float Min = 1e-8;
float calPreFix(char exp[], int len)
{
    float s[maxSize];
    int top = -1, i = len - 1;
    while (i >= 0)
    {
        if ('0' <= exp[i] && exp[i] <= '9')
        {
            s[++top] = exp[i--] - '0';
        }
        else
        {
            switch (exp[i--])
            {
            case '+':
                s[--top] = s[top] + s[top - 1];
                break;
            case '-':
                s[--top] = s[top] - s[top - 1];
                break;
            case '*':
                s[--top] = s[top] * s[top - 1];
                break;
            case '/':
                if (s[top - 1] < Min)
                {
                    cout << "Error";
                    return 0;
                }
                s[--top] = s[top] / s[top - 1];
            }
        }
    }
    return s[0];
}
int main()
{
    char s[maxSize] = {'+', '3', '*', '4',
                       '*', '5', '+', '2', '3'};
    cout << calPreFix(s, 9);
}
/*结果
103
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值