您的位置:首页 > 其它

自己模仿用堆栈写的计算器 有点混乱low 测试过没问题

2018-01-18 14:52 274 查看
主要思想是对每个输入的字符进行检测和分类,分成数字堆栈和符号堆栈然后判断符号优先级。
统一先处理乘号和除号,(如果有括号先处理括号,将括号内的运算处理完)
然后最后会出现优先级低的运算符加号 减号还没有运算完,字符串就结束了。
所以在最后又对堆栈进行处理,确保符号堆栈运算完(总之有点乱慎入。0.0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 50
//定义一个顺序存储栈
typedef struct
{
int data[MAXSIZE];
int top;
}SqStack;

/*******************栈的基本操作********************************/
int init_stack(SqStack *s)
{
s->top = -1;
return 1;
}

int clear_stack(SqStack *s)//清空
{
s->top = -1;
return 1;
}

int stack_empty(SqStack s)//判断
{
if (s.top == -1)
return 1;
else
return 0;
}

int stack_length(SqStack *s)//长度
{
return s->top + 1;
}

int push(SqStack *s, int e)//入
{
// printf("%c\n",e);
if (s->top == MAXSIZE - 1)
return 0;
s->top++;
s->data[s->top] = e;
return 1;
}

int pop(SqStack *s, int ee)//出
{
int f;
if (s->top == -1)
return 0;
f = s->data[s->top];
// printf("%d\n",f);
s->top--;
return f;

}

int mypop(SqStack *s)//出 了最后一个元素之后 top=-1
{
int f;
if (s->top == -1)
return 0;
f = s->data[s->top];
// printf("%c\n",f);
s->top--;
return f;

}

SqStack sign;
SqStack num;
SqStack *sign_flag=&sign;//符号
SqStack *num_s=#//数

int Priority(char op) //运算符的优先级
{
switch(op){
case '+':
case '-':return 1;
case '*':
case '/':return 2;
case '(':return 3;
default: return -1;
}
}

int Calculator(char *op,int results)
{
char *biaodashi=op;
char str[6]={0};
char *temp_num=str;
char num_flag=0;
char temp_signflag=0;
int op1,op2;
while(*biaodashi!='\0')//当字符串最后一个为空
{
while (*biaodashi >= '0' && *biaodashi <= '9') //如果是数字
{

*temp_num=*biaodashi;
*(temp_num+1)='\0'; //
temp_num++;
biaodashi++;
num_flag=1;
}

if(num_flag)
{
push(num_s,atoi(str)); //将一个数压入数据栈
temp_num=&str[0];
num_flag=0;
}

switch (*biaodashi)
{

case '+':
if(*biaodashi=='+' && stack_length(num_s)>=2 )//如果是+
{
temp_signflag=mypop(sign_flag); //将上一个符号和+比较
if(Priority('+') <= Priority(temp_signflag) && temp_signflag!='(')//如果 + 小于了 top符号
{
op1=mypop(num_s); op2=mypop(num_s);
//判断栈顶的运算符,以做出相应的运算
if(temp_signflag == '+') push(num_s, op1+op2);
else if(temp_signflag == '-') push(num_s,op2 - op1);
else if(temp_signflag == '*') push(num_s,op2 * op1);
else push(num_s,op2 / op1);
push(sign_flag,'+');
}
else
{
push(sign_flag,temp_signflag);
push(sign_flag,'+');
}
}
else
{
push(sign_flag,'+');
}
break;

case '-':
if(*biaodashi=='-' && stack_length(num_s)>=2)//如果是-
{
temp_signflag=mypop(sign_flag); //将上一个符号和+比较
if(Priority('-')<=Priority(temp_signflag) && temp_signflag!='(')//如果 + 小于了 top符号
{
op1=mypop(num_s);
op2=mypop(num_s);
//判断栈顶的运算符,以做出相应的运算
4000

if(temp_signflag == '+') push(num_s, op1+op2);
else if(temp_signflag == '-') push(num_s,op2 - op1);
else if(temp_signflag == '*') push(num_s,op2 * op1);
else push(num_s,op2 / op1);
push(sign_flag,'-');
}
else
{
push(sign_flag,temp_signflag);
push(sign_flag,'-');
}
}
else
{
push(sign_flag,'-');
}

break;

case '*':
if(*biaodashi=='*' && stack_length(num_s)>=2)//如果是*
{
temp_signflag=mypop(sign_flag); //将上一个符号和+比较
if(Priority('*')<=Priority(temp_signflag) && temp_signflag!='(')//如果 + 小于了 top符号
{
op1=mypop(num_s);
op2=mypop(num_s);
//判断栈顶的运算符,以做出相应的运算
if(temp_signflag == '+') push(num_s, op1+op2);
else if(temp_signflag == '-') push(num_s,op2 - op1);
else if(temp_signflag == '*') push(num_s,op2 * op1);
else push(num_s,op2 / op1);
push(sign_flag,'*');
}
else
{
push(sign_flag,temp_signflag);
push(sign_flag,'*');
}
}
else
{
push(sign_flag,'*');
}

break;

case '/':
if(*biaodashi=='/' && stack_length(num_s)>=2)//如果是/
{
temp_signflag=mypop(sign_flag); //将上一个符号和+比较
if(Priority('/')<=Priority(temp_signflag) && temp_signflag!='(')//如果 + 小于了 top符号
{
op1=mypop(num_s);
op2=mypop(num_s);
//判断栈顶的运算符,以做出相应的运算
if(temp_signflag == '+') push(num_s, op1+op2);
else if(temp_signflag == '-') push(num_s,op2 - op1);
else if(temp_signflag == '*') push(num_s,op2 * op1);
else push(num_s,op2 / op1);
push(sign_flag,'/');
}
else
{
push(sign_flag,temp_signflag);
push(sign_flag,'/');
}
}
else
{
push(sign_flag,'/');
}

break;

case ')':

do{
temp_signflag=mypop(sign_flag);
if(stack_length(num_s)>=2 && temp_signflag!='(')
{
op1=mypop(num_s);
op2=mypop(num_s);

//判断栈顶的运算符,以做出相应的运算
if(temp_signflag == '+') push(num_s,op1 + op2);
else if(temp_signflag == '-') push(num_s,op2 - op1);
else if(temp_signflag == '*') push(num_s,op2 * op1);
else if(temp_signflag == '/') push(num_s,op2 / op1);
}

printf("%d %d %c\n",op1,op2,temp_signflag);
}
while(temp_signflag!='(');//1+(2+3*2+3)
break;

case'('://如果是左括号
{
push(sign_flag,'(');//(1*(1-1)*(2+3*2+3))*2 1+(2+3)
}
break;

}
biaodashi++;
}

do{
if(stack_length(num_s)>=2)
{
op1=mypop(num_s);
op2=mypop(num_s);
temp_signflag=mypop(sign_flag);

//判断栈顶的运算符,以做出相应的运算
if(temp_signflag == '+') push(num_s, op1+op2);
else if(temp_signflag == '-') push(num_s,op2 - op1);
else if(temp_signflag == '*') push(num_s,op2 * op1);
else if(temp_signflag == '/') push(num_s,op2 / op1);

}
}
while((sign_flag->top +1));

printf("最后得到的结果:\n");
printf("%d",num_s->data[0]);

}

void Test()
{

char infix[MAXSIZE] = { 0 };
char postfix[MAXSIZE] = { 0 };
int result = 0;
printf("请输入一个表达式(确保能整除&没有等号):\n");
scanf("%s", infix);
Calculator(infix,result);

}

int main()
{
init_stack(sign_flag);
init_stack(num_s);
// int oop1=0;
// push(num_s,11); //将一个数压入数据栈
// printf("%d\n",num_s->top);
// printf("%d\n",num_s->data[num_s->top]);
// oop1=mypop(num_s);
// // oop1=pop(&num,oop1);
// printf("%d\n",oop1);//atoi 将字符串转化为整数
Test();
//system("pause");

return 0;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: