中序表达式转后序表达式(最全情况你想看的都在,c++)

题目:

表达式转换

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+-*\以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +

注意事项:

一定要注意小数,多位数字,负数,空格的情况

测试用例为:

序号输入输出说明
02+3*(7-4)+8/42 3 7 4 - * + 8 4 / +正常测试6种运算符
1((2+3)*4-(8+2))/52 3 + 4 * 8 2 + - 5 /嵌套括号
21314+25.5*121314 25.5 12 * +运算数超过1位整数且有非整数出现
3-2*(+3)-2 3 *运算数前有正负号
4123123只有一个数字
53 * ( 4 + 2 )3 4 2 + *有空格

步骤:

1.初始化一个栈stc:用来存各种各样的符号;初始化一个字符数组str来存最后结果;

2.从左至右扫描中缀表达式;

3.提取对象函数gotop,用来提取这个对象来应对多位数字如:1233,和负数的情况具体函数看代码;

​ 如果这个对象是个数就直接把他弄到数组里面,第一个肯定是数

4.遇到运算符时,比较其与stc栈顶运算符的优先级:
1.如果stc为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
2.否则,若优先级比栈顶运算符的高,也将运算符压入stc
3.否则,否则弹出栈中元素直到优先级比栈顶高或空栈为止;
5.遇到括号时:
1.如果是左括号“(”,则直接压入stc;
2.如果是右括号“)”,则依次弹出stc栈顶的运算符,并复制入str后面,直到遇到左括号为止,此时将这一对括号弹出;

6.如果遇到‘ ’,直接nexti++然后continue。

7.重复步骤2至5,直到表达式的最右边;
8.将stc中剩余的运算符依次弹出并复制入str;
9.即为中缀表达式对应的后缀表达式,输出数组即可

全注释代码:

#include <iostream>
#include <stack>
#include <string.h>
using namespace std;
///是否是数字
int IsNumber(char a)
{
    return a >= '0' && a <= '9';
}
///从字符串start处开始提取操作数或操作符,并返回下一次提取的开端和提取的对象
int getop(char *src, int start, int &nextstart, char *token) //这里用nextstart和token都是可以直接操作的
{
    int i, j;
    if (IsNumber(src[start]))
    {                                                                       ///是一个无符号数
        for (i = 0; IsNumber(src[start + i]) || src[start + i] == '.'; i++) //如果这一位是'.''或者是数字'就是把小数和多位数字都包括了
        {                                                                   ///复制给token
            token[i] = src[start + i];
        }
        token[i] = 0;
        nextstart = start + i; ///下一次提取的开端
        return 1;
    }
    else if ((src[start] == '+' || src[start] == '-') && (start == 0 || src[start - 1] == '('))
    { ///传进来的这一位是符号的话并且是一个负号数的话start == 0 || src[start - 1] == '('是限制符号数的
        if (src[start] == '-')
        {
            token[0] = src[start];
            j = 1; //负号的话就把负号给token[0]然后j=1就是从第二位开始把负号输进去
        }
        else
        {          ///去掉正号
            j = 0; //也就是直接把数输进去
        }
        for (i = 1; IsNumber(src[start + i]) || src[start + i] == '.'; i++)
        { ///复制给token
            token[j++] = src[start + i];
        }
        token[j] = 0;
        nextstart = start + i; ///下一次提取的开端
        return 1;
    }
    else
    {                          ///不是数
        token[0] = src[start]; ///复制操作符
        token[1] = 0;          //标识结束
        nextstart = start + 1; ///下一次提取的开端
    }
    return 0;
}
///定义优先级。括号最低
int Prior(char ch)
{
    int pri = 0;
    switch (ch)
    {
    case '(':
        pri = 1;
        break;
    case '+':
    case '-':
        pri = 2;
        break;
    case '*':
    case '/':
        pri = 3;
        break;
    }
    return pri;
}
///表达式转换
void Zhong2Hou(char *src, char *str) // str是装最后结果的数组
{
    stack<char> stc;
    int i, j, nexti;
    char token[100];
    for (i = 0, j = 0; src[i]; i = nexti)
    {
        if (src[i] == ' ')//如果为空格就不用管他
        {
            nexti++;
            continue;
        }

        int isnumber = getop(src, i, nexti, token); ///提取这个对象,就是处理多位数字和字母如果是个数就返回1了;
        if (isnumber)
        {              ///是个数
            int k = 0; ///复制到str后
            for (k = 0; token[k]; k++)
            {
                str[j] = token[k];
                j++;
            }
            str[j++] = ' '; ///用空格分隔,str就装数的对象了;
        }
        else if (src[i] == '(')
        { ///左括号直接入栈
            stc.push(src[i]);
        }
        else if (src[i] == ')')
        { ///右括号则弹出栈中全部操作符并复制到str后,直到左括号为止
            while (stc.top() != '(')
            {
                str[j++] = stc.top();
                stc.pop();
                str[j++] = ' '; ///用空格分隔
            }
            stc.pop(); ///弹出左括号
        }
        else
        { ///是个一般的四则运算符
            if (stc.empty())
            { ///空栈直接入栈
                stc.push(src[i]);
            }
            else if (Prior(src[i]) > Prior(stc.top()))
            { ///优先级高于栈顶则入栈
                stc.push(src[i]);
            }
            else
            { ///否则弹出栈中元素直到优先级比栈顶高或空栈为止
                while (!stc.empty() && Prior(src[i]) <= Prior(stc.top()))
                {
                    str[j++] = stc.top();
                    stc.pop();
                    str[j++] = ' ';
                }
                stc.push(src[i]); ///将该操作符入栈
            }
        }
    }
    while (!stc.empty())
    { ///弹出栈中全部元素
        str[j++] = stc.top();
        stc.pop();
        str[j++] = ' ';
    }
    str[j - 1] = 0; ///最后一个空格赋值为0就不打印最后的空格了
}
int main(void)
{
    char src[100] = "", str[100] = "";
    cin.getline(src, 100); ///输入
    Zhong2Hou(src, str);   ///转换
    cout << str;           ///打印
    system("pause");
    return 0;
}

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

c0re

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

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

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

打赏作者

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

抵扣说明:

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

余额充值