实现一个简单的计算器(不要求除法):如
输入:12+3*(5+6)*8
输出:276
输入:12+3*(5+6)*8
输出:276
感谢徐帅的代码,以下为改良版。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 100
#define MAX_LEN 100
typedef struct Element
{
int mark;//表示当前元素是数还是操作符,1 表示数,-1表示操作符
float data;
char op;
}Element;
typedef struct OpStack//中缀变后缀用的操作符暂存栈
{
char op;
struct OpStack *next;
}OpStack;
typedef struct FloatStack
{
float number;
struct FloatStack *next;
}FloatStack;
Element *MidToPost(char *str);
void ElementArrayPrint(Element *postorder);
float PostToResult(Element *postorder);
void OpStackPush(OpStack **t_ptr,char op);
char OpStackTop(OpStack *top);
char OpStackPop(OpStack **t_ptr);
void FloatStackPush(FloatStack **t_ptr,float number);
float FloatStackPop(FloatStack **t_ptr);
int main(void)
{
double res;
char *cmd = (char*)malloc(sizeof(char)*LEN);
memset(cmd,0,sizeof(char)*LEN);
printf("please input the calculation:\n");
scanf("%s",cmd);
Element *postorder=MidToPost(cmd);
printf("\nThe post order of s is:\n");
ElementArrayPrint(postorder);
if (cmd[0]>='0' && cmd[0]<='9')
{
res = PostToResult(postorder);
printf("the result is %f\n",res);
}
else
printf("input error!\n");
free(cmd);
return 0;
}
void OpStackPush(OpStack **t_ptr,char op)
{
OpStack *new_ptr=malloc(sizeof(OpStack));
new_ptr->op=op;
new_ptr->next=*t_ptr;
*t_ptr=new_ptr;
}
char OpStackTop(OpStack *top)
{
return top->op;
}
char OpStackPop(OpStack **t_ptr)
{
char ret=(*t_ptr)->op;
OpStack *new_top=(*t_ptr)->next;
free(*t_ptr);
*t_ptr=new_top;
return ret;
}
void FloatStackPush(FloatStack **t_ptr,float number)
{
FloatStack *new_ptr=malloc(sizeof(FloatStack));
new_ptr->number=number;
new_ptr->next=*t_ptr;
*t_ptr=new_ptr;
}
float FloatStackPop(FloatStack **t_ptr)
{
float ret=(*t_ptr)->number;
FloatStack *new_top=(*t_ptr)->next;
free(*t_ptr);
*t_ptr=new_top;
return ret;
}
Element *MidToPost(char *str)
{
Element *postorder=malloc(sizeof(Element)*MAX_LEN);//后缀存储数组
memset(postorder,0,sizeof(Element)*MAX_LEN);
OpStack *top=NULL;
float temp_num=0;//字符数字转换用临时存储
int post_pos=0;//后缀数组迭代器
char top_temp;//查看栈顶用临时缓存
char** read_end=&str;
char* read_temp=str;
while(**read_end!='\0')
{
//temp_num=strtod(read_temp,read_end);
//printf("读到一个数字%f\n",temp_num);
if(*read_temp>='0'&&*read_temp<='9')//读取到了数字
{
temp_num=strtod(read_temp,read_end);
postorder[post_pos].mark=1;
postorder[post_pos++].data=temp_num;
temp_num=0;
read_temp=*read_end;
}
else
{
if(*read_temp=='+'||*read_temp=='-')
{
while(top!=NULL&&OpStackTop(top)!='(')//遇到加减,把直到开头或左括号的所有操作符都放入数组
{
postorder[post_pos].mark=-1;
postorder[post_pos++].op=OpStackPop(&top);
}
OpStackPush(&top,*read_temp);
}
else if(*read_temp=='*'||*read_temp=='/')
{
while(top!=NULL&&((top_temp=OpStackTop(top))!='('&&top_temp!='+'&&top_temp!='-')) //遇到乘除,把直到开头或左括号或加减的操作符都放入数组
{
postorder[post_pos].mark=-1;
postorder[post_pos++].op=OpStackPop(&top);
}
OpStackPush(&top,*read_temp);
}
else if(*read_temp=='(')
OpStackPush(&top,'(');
else//只剩下右括号
{
while(OpStackTop(top)!='(')//把一直到左括号的操作符全放进去
{
postorder[post_pos].mark=-1;
postorder[post_pos++].op=OpStackPop(&top);
}
OpStackPop(&top);//把这个左括号也弹出去
}
*read_temp++;
}
}
while(top!=NULL)//读完后若操作符栈内还有剩余操作符,全部加入后缀
{
postorder[post_pos].mark=-1;
postorder[post_pos++].op=OpStackPop(&top);
}
return postorder;
}
void ElementArrayPrint(Element *postorder)
{
int i=0;
while(postorder[i].mark!=0)
{
if(postorder[i].mark==1)
printf("%5.1f",postorder[i].data);
else
printf("%5c",postorder[i].op);
++i;
}
}
float PostToResult(Element *postorder)
{
//注意:以下不添加任何对后缀表达式的检测,如果后缀转换出错那么废定了
FloatStack *top=NULL;
int i=0;
float temp1,temp2;
while(postorder[i].mark!=0)
{
if(postorder[i].mark==1)//是个男孩!啊不,是个数……
FloatStackPush(&top,postorder[i].data);
else//是个女孩!哎不是,是个操作符……
{
temp2=FloatStackPop(&top);
temp1=FloatStackPop(&top);//我擦这顺序真特么重要啊!
if(postorder[i].op=='+')
FloatStackPush(&top,temp1+temp2);
else if(postorder[i].op=='-')
FloatStackPush(&top,temp1-temp2);
else if(postorder[i].op=='*')
FloatStackPush(&top,temp1*temp2);
else
FloatStackPush(&top,temp1/temp2);
}
++i;
}
float ret=FloatStackPop(&top);
printf("For test:ret=%f\n",ret);
return ret;
}