有一段时间没有发博客了,在学习方面确实怠慢了很多很多。这学期学习了数据结构,突然想起之前发过一篇关于关于计算器的代码,然后刚刚好老师上课讲了对中缀表达式转后缀表达式计算的问题,本来是想把那个升级一下发个博客的,但奈何就在我刚刚准备发之前测试了一下,好像还是有一点点瑕疵。。。。。。就反正是这个修修改改的好几天了,虽然用的都是一些零碎的时间,但是还是很让人头疼。
其实我是感觉我的代码逻辑和思维是有一点点问题的,在网上有找过一些,不过就还是想先以自己的思维来做。不过现在实在不想接着改了,所以就先发出来,可能会有那么一点点瑕疵。
感觉我的代码应该不难理解,主要用了栈,然后其他的基本上感觉就是最陋的方法。
先发出来吧------------------------------------
#include<stdio.h>
#include<string.h>
#define MaxStackSize 100
typedef char DataType;
//创建栈的结构体
typedef struct{
DataType stack[MaxStackSize];
int top;
} SeqStack;
//初始化
void StackInitiate(SeqStack *S){
S->top = 0;
}
//判断非空否
int StackNotEmpty(SeqStack *S){
if(S->top <= 0){
return -1;
}else{
return 1;
}
}
//入栈
int StackPush(SeqStack *S,DataType x){
if(S->top >= MaxStackSize){
printf("Full!");
return 0;
}else{
S->stack[S->top] = x;
S->top ++;
return x;
}
}
//出栈
int StackPop(SeqStack *S,DataType d){
if(!StackNotEmpty){
printf("Empty!");
return 0;
}else{
S->top --;
d = S->stack[S->top];
return d;
}
}
//取栈顶数据元素
int StackTop(SeqStack *S,DataType d){
if(!StackNotEmpty){
printf("Empty!");
return 0;
}else{
int top = S->top - 1;
d = S->stack[top];
return d;
}
}
//打印栈元素
void Print(SeqStack *S){
DataType d;
while(StackNotEmpty(S) == 1){
d = StackPop(S,d);
printf("%c ",d);
}
}
//变成后缀表达式
char *Change(SeqStack *S,char str[]){
char str1[MaxStackSize];//用来存放变换后的后缀表达式
int count = 0;//计数
DataType x1,x2,y;
//x1 = StackTop(S,x1);//把栈顶元素赋值给 x1。
for(int i = 0;i < strlen(str);i ++){
x2 = str[i];//把数组的第i个值赋值给 x2。
if(x2 == '+' || x2 == '-' || x2 == '*' || x2 == '/' || x2 =='(' || x2 == ')' || x2 == '#'){//当 x2 是运算符时
x1 = StackTop(S,x1);//把栈顶元素赋值给 x1。
switch(x2){
case '#':
while(x1 != '#'){
str1[count] = StackPop(S,y);
x1 = StackTop(S,x1);//当有元素出栈时,要及时把更新的栈顶元素再赋值给 x1.
count ++;//如果 x2 是 #,且 x1 不为 # 的时候, x1 出栈。
}
return str1;
case '+':
if(x1 == '('){//当x2为 + 时,x1 的优先级大于 x2.
StackPop(S,y);//不考虑括号,所以括号出栈后不用存入数组
StackPush(S,x2);
}else if(x1 == '*' || x1 == '/'){//当 x1 的优先级大于 x2 时,x1出栈。
str1[count] = StackPop(S,y);
count ++;
StackPush(S,x2);//当把优先级大的 x1 出栈后,还需要把优先级小的 x2 入栈
}else{//否则 x2 入栈
StackPush(S,x2);
}
break;
case '-':
if(x1 == '('){//当x2为 * 时,x1 的优先级大于 x2.
StackPop(S,y);//不考虑括号,所以括号出栈后不用存入数组
StackPush(S,x2);
}else if(x1 == '*' || x1 == '/'){//当 x1 的优先级大于 x2 时,x1出栈。
str1[count] = StackPop(S,y);
count ++;
StackPush(S,x2);
}else{//否则 x2 入栈
StackPush(S,x2);
}
break;
case '*':
if(x1 == '('){//当x2为 * 时,x1 的优先级大于 x2.
StackPop(S,y);//不考虑括号,所以括号出栈后不用存入数组
StackPush(S,x2);
}else if(x1 == '*' || x1 == '/'){
str1[count] = StackPop(S,y);
count ++;
StackPush(S,x2);
}else{
StackPush(S,x2);
}
break;
case '/':
if(x1 == '('){//当x2为 / 时,
StackPop(S,y);//不考虑括号,所以括号出栈后不用存入数组
StackPush(S,x2);
}else if(x1 == '*' || x1 == '/'){
str1[count] = StackPop(S,y);
count ++;
StackPush(S,x2);
}else{
StackPush(S,x2);
}
break;
}
}else{//当 x2 不是运算符是,直接存入数组。
str1[count] = x2;
count ++;
}
}
return str1;
}
//后缀表达式计算
int AE(char str[]){
DataType y,z;
int x1,x2;
char str1[MaxStackSize];//存放数字
int count = 0;
SeqStack S1,S2;//S1存放数字,S2存放运算符
StackInitiate(&S1);//初始化
StackInitiate(&S2);
int sum = 0;
for(int i = strlen(str);i >= 0; i --){
y = str[i];
if(y == '+' || y == '-' || y == '*' || y == '/'){//当 y 为运算符的时候,存入S2中。
StackPush(&S2,y);
}else if(y >= '0' && y <= '9'){
str1[count] = y;
count ++;
}
}
count = 0;
x1 = str1[count] - 48;
count ++;
while(StackNotEmpty(&S2) == 1){
x2 = str1[count] - 48;
count ++;
z = StackPop(&S2,z);
switch(z){
case '+': {
sum = x2 + x1;
x1 = sum;
break;
}
case '-':{
sum = x2 - x1;
x1 = sum;
break;
}
case '*':{
sum = x2 * x1;
x1 = sum;
break;
}
case '/':{
sum = x2 / x1;
x1 = sum;
break;
}
}
}
return sum;
}
int main(){
int sum = 0;
char y = '#';
char str[MaxStackSize];//存放输入的算数表达式
char str1[MaxStackSize];//用来接收函数返回来的后缀表达式
SeqStack aStack;//定义一个结构体
StackInitiate(&aStack);//初始化
StackPush(&aStack,y);//将栈顶元素设置为 #。
//输入算术表达式,末尾要输入一个 # ,用来加以判断
printf("请输入中缀表达式:");
scanf("%s",str);
strcpy(str1,Change(&aStack,str));
printf("转换的后缀表达式为:");
printf("%s\n",str1);
//输出后缀表达式计算的结果
sum = AE(str1);
printf("计算的结果为:");
printf("%d",sum);
return 0;
}
2021-12-1
谢邀,最近有小伙伴问这个代码的怎么通过修改实现多位数字的加减乘除计算,但再经过修改的过程中,我发现我之前上面的那个代码本身存在很多问题。除了对计算位数的限制之外,代码在后缀表达式的计算上也存在问题。例如:
1、当输入的算式为1*2+3#时,
请输入中缀表达式:1*2+3#
转换的后缀表达式为:12*3+
计算的结果为:7
2、当输入的算式为3+2*1#时,
请输入中缀表达式:3+2*1#
转换的后缀表达式为:321*+
计算的结果为:5
这俩个算式的结果理应都为5的,中缀表达式转后缀表达式没有问题,但是,1 * 2+3# => 12 * 3+(后缀表达式) 这个式子在计算的时候的结果是7,通过测试我发现它在后缀表达式计算的时候是2 * 3+1的结果。但凡是a*(或/)b+(或-)c的型式,计算的结果就会变为b*(或/)c+(或-)a的结果。但是前缀表达式转中缀表达式应该没有问题,在此先写出我着半年前代码存在的问题。仅供参考。