一名大一初学狗,最近在学习栈的应用,在此记录解题代码:
** 题目描述 **
给出一个表达式,其中运算符仅包含+,-,*,/,^要求求出表达式的最终值 ,数据可能会出现括号情况, 还有可能出现多余括号情况 ,数据保证不会出现> maxlongint的数据 ,数据可能回出现负数情况
输入
仅一行,即为表达式
输出
仅一行,既为表达式算出的结果
样例输入
c (2+2)^(1+1)
样例输出
16
解题思路:
将中缀表达式转换成后缀表达式–>计算后缀表达式的值–>得出结果
转换成后缀表达式
第一步:建立两个栈number、symbol,分别用来存储后缀表达式,转换过程中运算符存储的空间。
第二步:依次对数据(给定的中缀表达式)进行操作:
-
遇到数字时,直接将数字压入number栈
-
遇到运算符时(包括对负数的处理):
若为 ( ,首先检测数据是否是负数,负数格式为(-x),检测下一位数据,若为-,则判定x为负数,进行相关操作。否则,直接将 ( 入symbol栈。
若为**)**:出栈所有运算符,并依次压入number栈,直到遇到 (,最后将 **(**出栈。
若为 ±*/^ ,首先判断此运算符的优先级是否大于symbol栈栈顶运算符,是则直接入symbol栈,
否则,symbol栈栈顶运算符出栈,随后压入number栈。再将此运算符入symbol栈,再与前一位运算符比较,重复上述操作,直到symbol栈栈顶运算符的优先级大于前一位运算符。 -
当数据都操作完后,出栈symbol栈中所有的运算符,依次压入number栈。
以 (2+2)^(1+1) -(-100) * 4/2 为例,结果为 2 2 + 1 1 + ^ -100 4 * 2 / -
后缀表达式的运算
建立一个新栈answer,扫描number栈,遇到数字就直接压入answer栈,遇到运算符,则取出answer栈栈顶的两个数字进行相应计算,运算的结果再入栈,直到扫描完,此时answer栈只剩下一个数值,即为最终结果。
以 2 2 + 1 1 + ^ -100 4 * 2 / - 为例
+——>2+2=4,+——>1+1=2,^ ——>4^2=16,* ——> (-100)*4=(-400),
/ ——>(-400)/2=(-200), – ——> 16-(-200)=216。
代码如下:
#include <stdio.h>
int flag;
struct Symbol
{
int top;
char s[100];
}symbol;
struct Number
{
int top;
char n[100];
}number;
struct Answer
{
int top;
int a[100];
}answer;
void init()
{
symbol.top = -1;
number.top = -1;
answer.top = -1;
}
//将运算符替换成数字以比较优先级
int replace(char a)
{
switch (a)
{
case '+':return 1;
case '-':return 1;
case '*':return 2;
case '/':return 2;
case '^':return 3;
case '(':return 0;
case ')':return 0;
}
}
//比较符号优先级
int compare(char s, char e)
{
return (replace(s) < replace(e)) ? 1 : 0;
}
//^运算符的计算操作
void fun()
{
if (answer.a[a