1、在vscode实现的,文件后缀是C++,写的时候纯C。
2、关于加入负数的计算,有BUG,因为操作数的缺省,导致栈空,会出错。但是可以实现(0-2)*(0-3)这样的含负数表达式。
3.关于小数的计算,看了其他文章,改下栈数据的类型,没试。
4、prinf1111\2222\5555之类,作为个人对代码的验证
5、代码编写参考:发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/149219.html原文链接:https://javaforall.cn
#include <bits/stdc++.h>
typedef struct node
{
int data;
struct node *next;
}StackNode,*PStackNode;
typedef struct
{
PStackNode top;
}LinkStack,*PLinkStack;
PLinkStack InitStack(void)
{
PLinkStack S;
S = (PLinkStack)malloc(sizeof(LinkStack));
if(S) S->top = NULL;
return S;
}
bool IsEmpty(PLinkStack S)
{
if(!S)
{
printf("栈不存在!\n");
return false;
}
if(S->top == NULL)
return true;
else
return false;
}
bool PushStack(PLinkStack S,int x)
{
if(!S)
{
printf("栈不存在!\n");
return false;
}
PStackNode p;
p = (PStackNode)malloc(sizeof(StackNode));
if(!p)
{
printf("申请内存失败!\n");
return false;
}
p->data = x;
p->next = S->top;
S->top = p;
return true;
}
bool PopStack(PLinkStack S,int *x)
{
if(!S)
{
printf("栈不存在!\n");
true;
}
if(IsEmpty(S))
{
printf("栈空!\n");
true;
}
PStackNode p;
p = S->top;
*x = p->data;
S->top = p->next;
free(p);
return true;
}
int GetTopElem(PLinkStack S)
{
if(!S)
{
printf("栈不存在!\n");
return -9999;
}
if(IsEmpty(S))
{
printf("栈空!\n");
return -9999;
}
return (S->top->data);
}
bool DestroyStack(PLinkStack *S)
{
PStackNode p,q;
if(*S)
{
p = (*S)->top;
while(p)
{
q = p;
p = p->next;
free(q);
}
free(*S);
}
*S = NULL;
return true;
}
//怕是否为数字
int IsNum(char c)
{
if(c>='0' && c<='9') return(1);
else return(0);
}
//判断是否为运算符
int IsOperation(char c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '#':
case '/':return(1);
case '(':return(2);
case ')':return(3);
default:
return(0);
}
}
//定义运算符优先级
int Priority(char c)
{
switch(c)
{
case '#':return(1);
case ')':return(2);
case '+':
case '-':return(3);
case '*':
case '/':return(4);
case '(':return(5);
default:return(0);
}
}
//定义运算操作
int operate(int a,char c,int b)
{
switch(c)
{
case '+':return a+b;
case '-':return a-b;
case '*':return a*b;
case '/':
if(b == 0)
{
printf("除数不能为0!\n");
exit(0);
}
else
return a/b;
}
}
int evaluate(char str[])
{
PLinkStack S1,S2;
int op;//存放弹出栈的运算符
int x = 0,a = 0,b = 0,x1 = 0,x2 =0;//存放计算中间值
int i = 0;
int result= 0;
S1 = InitStack();//存放操作符
S2 = InitStack();//存放操作数
if(PushStack(S1,'#'))
printf("操作符#已入栈!\n");
while(str[i] != '#' || GetTopElem(S1) != '#')
{
if(IsOperation(str[i]))//如果扫描的结果是运算符
{
printf("1111\n");
if(GetTopElem(S1) == '(' && IsOperation(str[i]) == 3)
{
PopStack(S1,&x);
i++;
}
else
{
if(GetTopElem(S1) == '(' || Priority(str[i]) > Priority(GetTopElem(S1)))
{
printf("2222\n");
PushStack(S1,str[i]);
i++;
}
else
{
while(Priority(str[i]) <= Priority(GetTopElem(S1)))
{
if(GetTopElem(S1) != '(')
{
PopStack(S1,&op);
printf("%c\n",op);
if(op == '#')
{
PushStack(S1,op);
break;
}
PopStack(S2,&a);
PopStack(S2,&b);//先弹出栈的是右操作数
PushStack(S2,operate(b,op,a));
}
else
{
if(str[i] == ')')
{
PopStack(S1,&op);
i++;
break;
}
else
{
PushStack(S1,str[i]);
i++;
break;
}
}
}
}
}
}
else if(IsNum(str[i]))//如果扫描的结果是操作数
{
printf("5555\n");
x1 = str[i]-'0';//字符型转换为数字
printf("%d\n",x1);
PushStack(S2,x1);
x2 = x1;
i++;
while(IsNum(str[i]))//归并思想组合多位数
{
x1 = str[i] - '0';
x2 = 10*x2 + x1;
PopStack(S2,&x);
PushStack(S2,x2);
i++;
}
}
else if(str[i] == ' ')//如过扫描的是空格
{
while(str[i] == ' ')
{
i++;
}
}
else//除以上三种情况之外,为非法数据
{
printf("error!\n");
printf("%d\n",i);
exit(0);
}
}
result = GetTopElem(S2);
DestroyStack(&S1);
DestroyStack(&S2);
return result;
}
int main()
{
char str[100]; //定义一个字符数组用于存储表达式,如果足够复杂的话也可以考虑单链表存储表达式
int result;
printf("Please Enter Expression:");//输入一定要以#结尾,因为while循环的判断条件为栈顶为#并且当前扫描的字符为#
gets(str);
puts(str);
result=evaluate(str);
printf("\n");
printf("%s\n%d\n",str,result);
return 0;
}
本文作为学习交流使用,欢迎大家指正与交流。