#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define END '\n'
char input_h = '\n';//定义全局变量,用于缓存输入慢速
char input_p = '\n';//定义全局变量,用于缓存输入
int temp = 0;//判断是否在完全入栈前进行运算
char optr[MAXSIZE]; //运算符栈
int optrTop; //运算符栈顶
double opnd[MAXSIZE]; //操作数栈
int opndTop; //操作数栈顶
void PushOptr(char x) { //运算符进栈
if (optrTop == MAXSIZE - 1) {
printf("运算符栈已满!上溢\n");
exit(1);
}
else
{
optrTop++;
optr[optrTop] = x;
}
}
void PushOpnd(double x) { //操作数进栈
if (opndTop == MAXSIZE - 1) {
printf("操作数栈已满!上溢\n");
exit(1);
}
else {
opndTop++;
opnd[opndTop] = x;
}
}
char PopOptr() { //运算符出栈
char y;
if (optrTop == -1) {
printf("输入有误\n");
exit(1);
}
else {
y = optr[optrTop];
optrTop--;
}
return y;
}
double PopOpnd() { //操作数出栈
double y;
if (opndTop == -1) {
printf("输入有误\n");
exit(1);
}
else {
y = opnd[opndTop];
opndTop--;
}
return y;
}
char GetTopOptr() { //取出运算符栈顶元素
if (optrTop != -1)
return optr[optrTop];
else {
printf("输入有误\n");
exit(1);
}
}
double gettop_opnd() { //取出操作数栈顶元素
if (opndTop != -1)
return opnd[opndTop];
else {
printf("输入有误\n");
exit(1);
}
}
void inistack_optr() { //初始化运算符栈
optrTop = -1;
}
void inistack_opnd() { //初始化操作数栈
opndTop = -1;
}
char Precede(char t1, char t2) { //判断优先级
char f;
switch (t2) {
case '+':
case '-':
if (t1 == '(' || t1 == END)
f = '<';
else
f = '>';
break;
case '*':
case '/':
if (t1 == '*' || t1 == '/' || t1 == ')')
f = '>';
else
f = '<';
break;
case '(':
if (t1 == ')') {
printf("输入有误\n");
exit(1);
}
else
f = '<';
break;
case ')':
switch (t1) {
case '(':
f = '=';
break;
case END:
printf("输入有误\n");
exit(1);
default:
f = '>';
}
break;
case END:
switch (t1) {
case END:
f = '=';
break;
case '(':
printf("输入有误\n");
exit(1);
default:
f = '>';
}
}
return f;
}
int char_In(char c) { //判断是否为运算符
switch (c) {
case '+':
case '-':
if ((!temp) && (char_In(input_h) || input_h == '\n')) {//检测上一个输入是否为操作符
PushOpnd(0);//向操作数栈填入一个0参与负数运算
}
return 1;
case '(':
if ((!temp)) {
if (input_h == ')' || (input_h >= '0' && input_h <= '9') || input_h == '.') {
printf("输入有误\n");
exit(0);
}
}
return 1;
case ')':
if ((!temp)) {
if (!((input_h >= '0' && input_h <= '9') || input_h == ')')) {
printf("输入有误\n");
exit(0);
}
}
return 1;
case '*':
case '/':
case END:
return 1;
default:
return 0;
}
}
double Operate(double a, char theta, double b) { //对出栈的两个数计算
double c;
switch (theta) { //运算符
case '+':
c = a + b; //输出0-9的ASCII码
break;
case '-':
c = a - b;
break;
case '*':
c = a * b;
break;
case '/':
c = a / b;
}
return c;
}
double EvaluateExpression() {
//使用运算符优先算法进行算术表示式求值
int cache_Len = 0, i, flag = 0;//计算连续输入数字个数
double a, b, curnum;//存储字符串转换成的小数
char stack_x, theta, input_c, buff[MAXSIZE];//存储数字字符串
inistack_optr(); //初始化运算符栈
PushOptr(END); //使结束符进栈
inistack_opnd(); //初始化操作数栈
input_c = getchar();//输入
stack_x = GetTopOptr();
while (input_c != END || stack_x != END) { //判断计算是否结束
if (char_In(input_c)) { //若输入的字符是7种运算符之一
input_h = input_c;//缓存上一个输入
for (i = 0; i < flag; i++) {//缓存字符串置空
buff[i] = '\0';
}
if (flag) {//将数字推向操作数栈
PushOpnd(curnum);
}
flag = 0;//标志回滚【+】
switch (Precede(stack_x, input_c)) {
case '<':
temp = 0;
PushOptr(input_c); //若栈顶(x)优先级<输入则输入进栈
input_c = getchar();
break;
case '=':
temp = 0;
stack_x = PopOptr();//相等则出栈
input_c = getchar();
break;
case '>':
temp++;
theta = PopOptr();
b = PopOpnd();
a = PopOpnd();
PushOpnd(Operate(a, theta, b));
break;
}
}
else if ((input_c >= '0' && input_c <= '9') || input_c == '.') { //input_c是操作数
if (input_h == ')') {//输入检查)右边不能为数字
printf("输入有误\n");
exit(0);
}
input_h = input_c;//缓存上一个输入
flag++;//标志计数增加
buff[flag - 1] = input_c;//输入的字符暂时存储到buff缓存字符串中
curnum = (double)atof(buff);//将字符串转换为小数
input_c = getchar();
}
else {
printf("输入有误\n");
exit(1);
}
stack_x = GetTopOptr();
}
return(gettop_opnd());
}
int main() {
printf("请输入算术表达式,以回车结束\n");
while (1) {
printf("%f\n", EvaluateExpression());
}
}
利用堆栈实现计算器
猜你喜欢
转载自blog.csdn.net/weixin_52088967/article/details/124026860
今日推荐
周排行