下面的代码实现目标:
- 实现对逆波兰输入的表达式进行计算
- 支持带小数点的数据
话不多说上代码:
#include "Link_head.h"
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define MAXBUFFER 10
int main(void)
{
struct LinkStack* s = (LinkStack*)malloc(sizeof(LinkStack));
char c = 0;
char str[MAXBUFFER];//作为一个缓存区
int i = 0;
double a, b;
s->top = NULL;
s->count = 0;
printf("请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以'#'作为结束标志\n");
scanf_s("%c",&c,1);
while (c != '#') {
i = 0;
while (isdigit(c) || c == '.') {
str[i++] = c;
str[i] = '\0';
scanf_s("%c", &c,1);
if (c == ' ') {
Push(s,atof(str));
break;
}
}
switch (c) {
case '+':
Pop(s, &b);
Pop(s, &a);
Push(s, a + b);
break;
case '-':
Pop(s, &b);
Pop(s, &a);
Push(s, a - b);
break;
case '*':
Pop(s, &b);
Pop(s, &a);
Push(s, a * b);
break;
case '/':
Pop(s, &b);
Pop(s, &a);
if(b == 0){
printf("\n出错:除数不能为零\n");
return -1;
}
Push(s, a / b);
break;
}
scanf_s("%c", &c, 1);
}
Pop(s, &a);
printf("最终的结果为:%f\n",a);
return 0;
}
因为我用的是vs,所以scanf不一样直接改一下就可以了。还有就是栈的相关函数在我之前的文章里面:链栈的代码实现
关键代码讲解
1.过滤掉数据部分
i = 0;
while (isdigit(c) || c == '.') {
str[i++] = c;
str[i] = '\0';
scanf_s("%c", &c,1);
if (c == ' ') {
Push(s,atof(str));
break;
}
}
我们把0到9之间的数字字符和小数点存到我们的数据缓存区中,当遇到空格的时候就把字符串转换成浮点型的数据存入栈中,这样就可以把数据先过滤掉了。
给大家简单介绍一下isdigit()和atof():
int isdigit( int ch ):
包含头文件:#include <ctype.h>
【功能】若果参数是0到9之间的数字字符,函数返回非零值,否则返回零。
double atof(const char *str):
包含头文件:#include <stdlib.h>
【功能】把字符串转化为浮点型数据
注意:
- i在循环中必须要初始化为零
- 这个非常重要:
str[i] = '\0';
2.整体算法处理过程
switch (c) {
case '+':
Pop(s, &b);
Pop(s, &a);
Push(s, a + b);
break;
case '-':
Pop(s, &b);
Pop(s, &a);
Push(s, a - b);
break;
case '*':
Pop(s, &b);
Pop(s, &a);
Push(s, a * b);
break;
case '/':
Pop(s, &b);
Pop(s, &a);
Push(s, a / b);
if(b == 0){
printf("\n出错:除数不能为零\n");
return -1;
}
break;
}
scanf_s("%c", &c, 1);
这个思路很简单,就是当遇到运算符时把栈顶的两个元素拿出来,运算完之后在将计算结果入栈,然后当所有数据都运算完之后就只有一个数据了,拿出来就是运算结果了。
当然还可以加上%、^等等的运算符,或者是sin这样的正弦函数,让这个计算器的功能更加丰富。
注意: 在除法的时候,除数不能为零,这个不要忽略
总结
没有调试结果的代码不是好代码!
我们把(1-2)*(4+5)转化为后缀表达式输入:1 2 - 4 5 + * ,然后得到结果:-9
如果有正在学数据结构的兄弟们可以一起交流哦!放假在家实在太难学习,慢慢坚持加油吧!
明天学中缀表达式转化为后缀表达式,肝肝赶!