本文非原创。
目的:输入一个中缀表达式,求解表达式的值。eg:20*(4.5-3)=
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10//存储空间增量
typedef char ElemType;
typedef int Status;
typedef struct { //存储运算符号*/+-()=
ElemType* base;
ElemType* top;
int stacksize;//当前分配的存储空间,以元素为单位。
}SqStack, * SqStacklist;
typedef struct { //存储运算数
double* base;
double* top;
int stacksize;
}SqStack1, * SqStacklist1;
//栈的初始化
SqStacklist InitStack() {
SqStacklist S;
S = (SqStacklist)malloc(sizeof(SqStack));
S->base = (ElemType*)malloc(STACK_INIT_SIZE * sizeof(ElemType));
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return S;
}
SqStacklist1 InitStack1() {
SqStacklist1 S;
S = (SqStacklist1)malloc(sizeof(SqStack1));
S->base = (double*)malloc(STACK_INIT_SIZE * sizeof(double));
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return S;
}
// e返回顶数值,并且删除栈顶数值
Status Pop1(SqStacklist1 S,double *e) {
if (S->top == S->base) return 0;
*e = *--S->top;
}
Status Pop(SqStacklist S, ElemType* e) {
if (S->top == S->base) return 0;
*e = *--S->top;
}
void DeleteTop(SqStacklist S) {
S->top--;
}
//元素入栈
void Push(SqStacklist S, ElemType e) {
if (S->top - S->base >= S->stacksize) {
S->base = (ElemType*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(ElemType));
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = e;
}
void Push1(SqStacklist1 S, double e) {
if (S->top - S->base >= S->stacksize) {
S->base = (double*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(double));
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = e;
}
//得到栈顶元素和pop区别是这里只能得到栈顶元素S->top - 1
ElemType GetTop(SqStacklist S) {
ElemType e = *(S->top - 1);
return e;
}
double GetTop1(SqStacklist1 S) {
double e = *(S->top - 1);
return e;
}
//判断两个符号的优先关系;从该链接可以看到解释:https://blog.youkuaiyun.com/yuluows/article/details/7657944
char Precede(char theta1, char theta2)
{
int i, j;
char pre[][7] = {
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='} };
switch (theta1) {
case '+': i = 0; break;
case '-': i = 1; break;
case '*': i = 2; break;
case '/': i = 3; break;
case '(': i = 4; break;
case ')': i = 5; break;
case '=': i = 6; break;
}
switch (theta2) {
case '+': j = 0; break;
case '-': j = 1; break;
case '*': j = 2; break;
case '/': j = 3; break;
case '(': j = 4; break;
case ')': j = 5; break;
case '=': j = 6; break;
}
return(pre[i][j]);
}
//进行运算
double Operate(double a, char theta, double b)
{
switch (theta) {
case'+':return a + b;
case'-':return a - b;
case'*':return a * b;
case'/': //判断除数是否为0,若除数为零返回错误提示
if (b != 0)
return a / b;
else
{
printf("分母不能为0!\n");
exit(0);
}
}
}
//判断是否是运算符
int In(char c)
{
switch (c) {
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':
return 1;
default:
return 0;
}
}
//计算
double Calculate(char str[]) {
SqStacklist S;
SqStacklist1 S1;
S = InitStack(); //存放符号
S1 = InitStack1(); //存放数值
double a, b,dtemp;
ElemType theta;
int i = 0;
Push(S, '=');
if (str[i] == '=') { //若第一个字符为‘=’,则直接退出
exit(0);
}
Push1(S1, 0); //事先向S1中压入0,防止第一个数为负数而导致异常
while (str[i] != '=' || GetTop(S) != '=') //表达式没有扫描完毕或S1的栈顶不为“=”
{
int m = 0;
if (In(str[i])) //判断是否为操作符
{
switch (Precede(GetTop(S), str[i]))//比较str[i]与S1栈顶元素的优先级
{
case'<'://栈顶元素的优先权较低
Push(S, str[i++]);
break;
case'>'://退栈并将结果入栈
Pop(S, &theta);
Pop1(S1, &b);
Pop1(S1, &a);
Push1(S1, Operate(a, theta, b));
break; //i没有++,意味着继续读这个符号,即str[i]没变
case'=':
DeleteTop(S); //脱括号并接受下一字符; 即栈顶为‘(',str[i]为')',此时将栈顶元素删除即可
i++;
break;
}
}
else if ((str[i] >= '0' && str[i] <= '9') || str[i] == '.') //判断是否为数字
{
char num[100] = {};
int j = 0;
while ((str[i] >= '0' && str[i] <= '9') || str[i] == '.') { //生成数
num[j++] = str[i];
if ((str[i + 1] >= '0' && str[i + 1] <= '9') || str[i + 1] == '.') i++;
else break;
}
dtemp = atof(num);
Push1(S1, dtemp);
i++;
}
else
{
printf("输入非法字符\n"); //返回错误提示
exit(0);
}
}
return(GetTop1(S1)); //最后返回操作数栈顶为运算结果
}
int main() {
while (1) {
char str[100]; //存储表达式
printf("请输入表达式:\n");
scanf("%s", str);
double result = Calculate(str);
printf("结果是:%.2f\n\n", result);
}
return 0;
}
同学希望帮到你。