#include<stack>
using namespace std;
//判断是否是运算符,是的话返回true否则返回false
bool tell(char ch)
{
char ops[] = "+-*/";
for (int i = 0; i < sizeof(ops) / sizeof(char); i++)
{
if (ch == ops[i])
return true;
}
return false;
}
// 比较两个操作符的优先级
int Precedence(char op1, char op2)
{
if (op1 == '(')
return -1;
if (op1 == '+' || op1 == '-')
{
if (op2 == '*' || op2 == '/')
return -1;
else
return 0;
}
if (op1 == '*' || op1 == '/')
{
if (op2 == '+' || op2 == '-')
return 1;
else
return 0;
}
}
// 中缀表达式转换成后缀表达式
/*
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
*/
void change(char* inFix, char* postFix)
{
int j = 0, len, m, k = 0;
char c;
stack<int> st;
len = strlen(inFix);
for (int i = 0; i < len; i++)
{
c = inFix[i];
if (c == '(')//遇到(,直接入栈
{
st.push(c);
}
else if (c == ')')//遇到)进行判断
{
while (st.top() != '(')
{
m = j;
if (m >= 1 && (tell(postFix[--m]) == true))//前面是运算符,就不要加空格了
{
postFix[j++] = st.top();//栈顶不是左括号,出栈,进入后缀表达式
st.pop();
m = j;
}
else
{
postFix[j++] = ' ';
postFix[j++] = st.top();//栈顶不是左括号,出栈,进入后缀表达式
st.pop();
}
}
st.pop();
}
else
{
if (!tell(c))//如果c不是运算符不是括号,直接输出到后缀表达式
postFix[j++] = c;//st.push(c)
else//是运算符
{
m = j;
if (m >= 1 && (tell(postFix[--m]) == true))//前面是运算符,就不要加空格了
{
while (st.empty() == false && Precedence(st.top(), c) >= 0)//遇到运算符,栈非空,弹出所有优先级大于或者等于该运算符的栈顶元素
{
postFix[j++] = st.top();//先取值
st.pop();//再删除
m = j;
}
}
else
{
postFix[j++] = ' ';
while (st.empty() == false && Precedence(st.top(), c) >= 0)//遇到运算符,栈非空,弹出所有优先级大于或者等于该运算符的栈顶元素
{
postFix[j++] = st.top();//先取值
st.pop();//再删除
}
}
st.push(c);//栈为空,遇到运算符则运算符直接入栈or上一步之后将该运算符入栈
}
}
}
while (st.empty() == false)//最后栈依旧不是空的,则全部出栈
{
m = j;
if (m >= 1 && (tell(postFix[--m]) == true))//前面是运算符,就不要加空格了
{
postFix[j++] = st.top();
k++;
st.pop();
}
else
{
postFix[j++] = ' ';//!
postFix[j++] = st.top();
k++;
st.pop();
}
}
postFix[j] = 0;
}
// 后缀表达式求值
int postFixEval(char* postFix, int* a, int* b)
{
stack<int> st;//int型的栈,还是char型的栈!!!!!
int len = strlen(postFix), y = 0;
char c;
*a = 0;
*b = 1;
for (int i = 0; i < len; i++)
{
c = postFix[i];
if (tell(c) == false)//不是运算符
{
if (c >= '0' && c <= '9')
{
int int_c = (int)(c - '0');//强制转换
y = y * 10 + int_c;
}
else if (c == ' ')
{
st.push(y); y = 0;
}
}
else
{
int op1, op2;
int res = 0, z = 0;
op1 = st.top();
st.pop();
op2 = st.top();
st.pop();
switch (c)
{
case '+':
res = op1 + op2;
break;
case '-':
res = op2 - op1;
break;
case '*':
res = op1 * op2;
break;
case '/':
if (op1 != 0)
res = op2 / op1;
else
{
int temp;
temp = *b;
*a = temp;
goto second;
}
second: break;
}
st.push(res);
}
}//printf("zhedaodishisha,%d",sizeof(st.top()));//这就已经是-128,是char的
return st.top();
}
//操作函数
int exe()
{
char inFix[100];
char postFix[100];
int val;
int z = 0, z1 = 1;
re:printf("请输入一个中缀表达式\n");
while (1)
{
gets_s(inFix);
if (strlen(inFix) == 0)
continue;
change(inFix, postFix);
printf("后缀表达式为 %s ", postFix);
printf("\n");
val = postFixEval(postFix, &z, &z1);
if (z == 0)
{
//if (val >= 0)
printf("结果是%d\n", val);
/*else
{
s++;
val2 = val2+256;//可以在一部分内进行两位数加减了,但是范围有待扩大;
printf("结果是%.01f\n", val);
}*/
}
else
{
printf("输入表达式不合法,除数不能为0,请重新输入,谢谢\n");
goto re;
}
return 0;
}
}
int main()
{
char inFix[100];
int a;
while (1)
{
printf("------------操作菜单------------\n");
printf(" 1:执行操作 ");
printf("2:退出程序\n");
printf("--------------------------------\n");
printf(" 按数字键选择要执行的操作: \n");
scanf_s("%d", &a);
printf("\n");
if (a == 2)
break;
switch (a)//如果输入错误,带*/号就无限循环
{
case 1:exe(); break;
default:
printf("输入的数字不正确,请重新输入\n");
break;
}
}
return 0;
}
基本没有问题