ZJNU 数据结构oj 1004 编译器中的表达式求值问题

Description

按中缀形式输入一个四则运算的表达式,利用算法优选算法把其转换为后缀表达式输出,并求表达式的值。假设输入的表达式中的操作数都是1位整数。

Input

输入数据有多组 每一组测试数据为带小括号的四则运算中缀表达式,不包含空格。

Output

对于每组测试数据输出两行,第一行四则运算表达式的后缀表达式(每个数字或者操作符之间输出空格,最后一个元素后没有空格),第二行运算结果。 除法操作为整除,比如6/4=1。

Sample Input

8-(3+2*6)/5+4
(7+8)*9
Sample Output

8 3 2 6 * + 5 / - 4 +
9
7 8 + 9 *
135

tips:
定义栈时不可以使用char要用int,要不然就会出现只要大于128就会变成负数的情况,因为char只能存储那么大,再打就涉及编码变成负数了

代码区:

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
using namespace std;
int size = 1005;
typedef struct{
    int* top;
    int* base;
}SqStack;

char op[][8] = {//不同符号的优先级,为了方便所以用二维数组的形式来存储
        //分别为+-*/()#
        {">><<<>>"},
        {">><<<>>"},
        {">>>><>>"},
        {">>>><>>"},
        {"<<<<<=>"},
        {">>>>>>>"},
        {"<<<<<<="}
};

char oop[8] = "+-*/()#";//符号查询对应的数字
char Precede(char a, char b){//比较函数,比较两数的大小,返回>或<等
    int temp1 = 0;
    int temp2 = 0;
	for(int i = 0;i < 8;i++){
	    if(a == oop[i])temp1 = i;//取出对应符号的数字,来获取大小优先关系
	    if(b == oop[i])temp2 = i;
    }
    return op[temp1][temp2];
}

int Operate(int a, char theta, int b){//运算函数,很简单
    if (theta == '+'){
        return a+b;
    }else if(theta == '-'){
        return a-b;
    }else if(theta == '*'){
        return a*b;
    }else if(theta == '/'){
        return a/b;
    }
}

int InitStack(SqStack &s){//初始化栈函数
    s.base = (int*) malloc(size*sizeof(int));//开辟空间来给栈,这里先随便来一个1005,应该够用了,小了可能会Runtimeerror
    s.top = s.base;//top和base初始设为一样的
    return 1;
}
int GetTop(SqStack &s){//获取栈顶的元素
    if(s.top == s.base)return 0;//这就说明栈是空的
    return *(s.top - 1);//因为栈的top是不存在的数,所以需要往下-1
}
int Push(SqStack &s,int e){//将数字推入栈
    *s.top ++ = e;//此处先将e的值存储栈,然后将top++,先后顺序注意
    return 1;
}
int Pop(SqStack &s,int &e){//弹出栈顶的数字元素同时将那元素存入e中
    if(s.top == s.base)return 0;
    e = (int)*(--s.top);//因为s中存的是char型,所以要用int强转一下
    return 1;
}
int Cpop(SqStack &s,char &e){//弹出栈顶的字符元素同时将那元素存入e中
    if(s.top == s.base)return 0;
    e = *(--s.top);//注意这里的顺序是先执行--再是取top的值
    return 1;
}
void Evaluate(char ch){//转化函数,将中序表达式转化成后序表达式
    SqStack opnd,optr,rear;//opnd栈储存操作数,optr栈存储操作符,rear存后序表达式
    InitStack(opnd);//初始化栈
    InitStack(optr);
    InitStack(rear);
    int a,b;
    char x;
    char theta;
    Push(optr,'#');//先把#退入optr中,作为判断栈空的条件
    while(ch!='#'||GetTop(optr)!='#'){//当读入的字符不为#同时操作符栈顶元素不是#时
        if((ch >= '0') && (ch <= '9')){//
            Push(opnd,ch - '0');//因为ch是字符型所以需要减去'0'来转化成数字型存入opnd
            Push(rear,ch);//如果是数字就直接推入后续表达式中
            ch = getchar();//获取下一个字符
            if(ch == '\n')ch = '#';//由题目知,只有一行所以当读到的字符是回车时判断输入结束,将之替换成#
        }
        else
            switch(Precede(GetTop(optr),ch)){//判断ch和操作符栈顶的元素之间的优先关系
                case '=':
                    Cpop(optr,x);//当优先级相同时也就意味着是一对括号,所以直接取出optr中的(就好了,所以就直接弹出
                    ch = getchar();
                    if(ch == '\n')ch = '#';
                    break;
                case '>'://如果栈顶的优先级高就进行运算
                    Cpop(optr,theta);//弹出栈顶的操作符
                    Pop(opnd, b);//这里有先后顺序,先弹出b再是a
                    Pop(opnd, a);
                    Push(rear, theta);//将即将进行运算的操作符存入后续表达式中
                    Push(opnd, Operate(a, theta, b));//将运算后的结果再存入操作数中
                    break;
                case '<':
                    Push(optr,ch);//如果优先级高于栈顶元素就推入栈
                    ch = getchar();
                    break;
            }
    }
    opnd.top = opnd.base;//将opnd栈置空,这里将top和base相等也可以达到这个效果
    int *p = rear.base;//新定义一个p指针来获取后缀表达式
    while(p!=rear.top)//意思是当rear栈不为空时
    {
        cout << (char)*p << " ";//因为是int型所以需要强转成char
        if(*p >= '0' && *p <= '9')
            Push(opnd,*p - '0');//是数字就直接推入操作数栈
        else//是操作符就直接进行运算
        {
            Pop(opnd,b);
            Pop(opnd,a);
            Push(opnd, Operate(a,*p,b));
        }
        p++;//取下一个字符
    }
    cout << endl << GetTop(opnd) << endl;//此处的opnd中只有一个数,也就是我们需要求的结果
}
int main(){
    char ch;
    while(cin >> ch){
        if(ch != '\n')Evaluate(ch);//当读入数据不是回车符时,进行转化函数
    }
    return 0;
}

新手上路,有错请指正.

下面是一个 Python 程序,可以将中缀表达式转换后缀表达式,并计算出表达式的值: ```python def infix_to_postfix(expression): # 定义运算符的优先级 priority = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 0, ')': 0} # 初始化一个空和一个空列表 stack = [] postfix = [] # 遍历表达式的每个字符 for char in expression: # 如果是数字,直接添加到后缀表达式 if char.isdigit(): postfix.append(char) # 如果是左括号,将其压入 elif char == '(': stack.append(char) # 如果是右括号,将的运算符弹出并添加到后缀表达式,直到遇到左括号 elif char == ')': while stack[-1] != '(': postfix.append(stack.pop()) stack.pop() # 如果是运算符,将优先级大于等于它的运算符弹出并添加到后缀表达式,然后将其压入 elif char in '+-*/': while stack and priority[stack[-1]] >= priority[char]: postfix.append(stack.pop()) stack.append(char) # 将剩余的运算符弹出并添加到后缀表达式 while stack: postfix.append(stack.pop()) # 返回后缀表达式 return postfix def evaluate_postfix(postfix): # 初始化一个空 stack = [] # 遍历后缀表达式的每个元素 for char in postfix: # 如果是数字,将其转换为整数并压入 if char.isdigit(): stack.append(int(char)) # 如果是运算符,弹出顶的两个元素进行计算,并将结果压入 elif char in '+-*/': op2 = stack.pop() op1 = stack.pop() if char == '+': result = op1 + op2 elif char == '-': result = op1 - op2 elif char == '*': result = op1 * op2 elif char == '/': result = op1 / op2 stack.append(result) # 返回顶的元素即为表达式的值 return stack[-1] # 主程序 expression = input("请输入中缀表达式:") postfix = infix_to_postfix(expression) print("后缀表达式为:", ' '.join(postfix)) value = evaluate_postfix(postfix) print("表达式的值为:", value) ``` 程序首先定义了运算符的优先级,并使用和列表两个数据结构中缀表达式转换后缀表达式。然后再使用计算出后缀表达式的值,并输出结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Khalil三省

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

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

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

打赏作者

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

抵扣说明:

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

余额充值