(中缀表达式)编写进栈、出栈、表达式求值等相关函数,实现表达式求值功能。
前情提要
纯c版本,它可以无限输入,输出;不断进行表达式计算,退出就直接把控制台关掉就好。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define max 100
typedef struct
{
double data[max];
int top;
}Stacknum;
typedef struct
{
char data[max];
int top;
}Stackchar;
void initnum(Stacknum *p)
{
p->top=0;
}
void initchar(Stackchar *p)
{
p->top=0;
}
void pushnum(Stacknum *p,int e)
{
if(p->top==max) printf("int栈溢出");
else p->data[p->top++]=e;
}
void pushchar(Stackchar *p,char e)
{
if(p->top==max) printf("char栈溢出");
else p->data[p->top++]=e;
}
void popnum(Stacknum *p,int *e)
{
if(p->top==0)//p-top最初是0,当有数据输入就往上加一格
printf("int栈为空\n");
else
{
p->top--;//top退一位,指向顶部数据
*e=p->data[p->top];
}
}
void popchar(Stackchar *p, char *e)
{
if (p->top == 0)
printf("char栈空\n");
else
{
p->top--;
*e = p->data[p->top];
}
}
void fun(Stacknum *p,char e)
{
int temp1,temp2;
popnum(p,&temp2);//后进的,先退出并取值
popnum(p,&temp1);
switch(e)
{
case '+':pushnum(p,temp1+temp2);break;
case '-':pushnum(p,temp1-temp2);break;
case '*':pushnum(p,temp1*temp2);break;
case '/':pushnum(p,temp1/temp2);break;
}
}
float getnum(Stacknum p)
{
int temp=p.top-1;
return p.data[temp];
}
int calculation(Stacknum *n1,Stackchar *c1)
{
int i;//循环变量
int temp;//存放一个临时转换数
char str[max], ch;//存放中缀表达式原式,临时运算符
for (;;)
{
printf("请输入中缀表达式:");
gets(str);
for (i = 0; str[i] != '\0'; i++)//读完整字符串-----字符串结束标志'\0'
{
if (str[i] >= '0'&&str[i] <= '9')//分岔点一:遇到的是数字
{
temp = str[i] - '0';//-----将字符转换为数值
while (str[i + 1] != '\0')//多位数值获取
{
if (str[i + 1] >= '0'&&str[i + 1] <= '9')
{
temp = temp * 10 + str[i + 1] - '0';//---减去0的ascii,获得数字
i++;
}
else
break;//如果不是多位数字,则跳出多位获取循环
}
pushnum(n1, temp);//将获取来的数值入栈
}
else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '(' || str[i] == ')')//分岔点二:遇到的是运算符
{
switch (str[i])//表达式可为:整型/字符型/枚举型-----C语言中
{
//case 后可为 整型,字符型----C语言中
case '+':
if (c1->data[c1->top - 1] != '+'&&c1->data[c1->top - 1] != '-'&&c1->data[c1->top - 1] != '*'&&c1->data[c1->top - 1] != '/')
{
pushchar(c1, '+');
}
else//如果不然,则将之前的先都出栈并计算,然后再入栈
{
while (c1->top > 0 && c1->data[c1->top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高
{
popchar(c1, &ch);
fun(n1, ch);//计算,并压运算数栈
}
pushchar(c1,'+');
}break;
case '-':
if (c1->data[c1->top - 1] != '+'&&c1->data[c1->top - 1] != '-'&&c1->data[c1->top - 1] != '*'&&c1->data[c1->top - 1] != '/')
{
pushchar(c1, '-');
}
else//如果不然,则将之前的先都出栈并计算,然后再入栈
{
while (c1->top > 0 && c1->data[c1->top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高
{
popchar(c1, &ch);
fun(n1, ch);//计算,并压运算数栈
}
pushchar(c1, '-');
}break;
case '*':
if (c1->data[c1->top - 1] != '*'&&c1->data[c1->top - 1] != '/')
{
pushchar(c1, '*');
}
else//如果不然,则将之前的先都出栈并计算,然后再入栈
{
while (c1->top > 0 && c1->data[c1->top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高
{
popchar(c1, &ch);
fun(n1, ch);//计算,并压运算数栈
}
pushchar(c1, '*');
}break;
case '/':
if (c1->data[c1->top - 1] != '*'&&c1->data[c1->top - 1] != '/')
{
pushchar(c1, '/');
}
else//如果不然,则将之前的先都出栈并计算,然后再入栈
{
while (c1->top > 0 && c1->data[c1->top - 1] != '(')//将优先级高的运算符先输出计算,其中括号内的优先级最高
{
popchar(c1, &ch);
fun(n1, ch);//计算,并压运算数栈
}
pushchar(c1, '/');
} break;
case '(':
pushchar(c1, '(');break;
case ')'://并没有将'('压入栈中,只是当作一种出栈信号
while (c1->data[c1->top - 1] != '(')
{
popchar(c1, &ch);
fun(n1, ch);//计算,并压运算数栈
}
popchar(c1, &ch);//将'('也出栈,但并不计算
break;
}
}
}
while(c1->top>0)//将剩余的运算符出栈并计算
{
popchar(c1, &ch);
fun(n1, ch);
}
printf("%s=%.2f",str,getnum(*n1));
printf("\n");
system("pause");//来暂停黑窗口
}
}
void main()
{
Stacknum n1;
Stackchar c1;
initnum(&n1);
initchar(&c1);
calculation(&n1,&c1);
}
输出
输入
3*(7-2)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)