logo资料库

C语言:中缀算术表达式求值(栈 附答案).docx

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
中缀算术表达式求值
题目
算法
代码实现
中缀算术表达式求值 题目 输入一个中缀算术表达式,计算其结果。对输入的表达式,做如下假设: (1) 只考虑+、-、*、/这四种运算符,中缀表达式中只有一种括号(); (2)输入的中缀表达式中数字只有整数,没有小数; (3)假定输入表达式是合法的。 算法 基本思路:设置两个工作栈,都为链栈,一个存储操作数,一个存储运算符。 然后输入想要求解的表达式,表达式不正确则需要重新输入,最后输出结果 主要的两个工作函数的基本算法 1. compare()函数 1) 遍历输入的字符串 y[] 2) 当遇到操作数时,操作数进操作数栈 3) 当遇到运算符时,判断其是否为( ,是则进入 4),不是则进入 5) 4) 如果后面跟的是操作数或者是( 都入栈,直到遇到第一个非( 的运算 符将其压入运算符栈 5) 当该运算符是否为) 且栈顶元素为( 两者满足将栈顶元素(弹出 6) 取出该运算符的标志位,与栈顶元素的标志位比较,若该运算符的标志 位大则该运算符进栈,否则进行 yunsuan()操作,直到该运算符为#且栈 顶元素为#时,将结果输出 2. yunsuan()函数 从操作数栈中弹出两个量 n1,n2,从运算符栈中弹出一个量 op,通过判断 op 是四则运算中的哪个将 n1 和 n2 进行运算,并将运算结果压入操作数栈 中 注意:这里运算符的优先级别是这样规定的* / 3 + - 2 ) 1 # 0
没有给(进行优先级别的运算,而是遇到( 直接将其压入栈内,并将第一个不为(的 字符(包括该字符)都压入栈内 代码实现 #include #include #include #include #define SIZE1 sizeof(struct stack1) #define SIZE2 sizeof(struct stack2) //进行重新设计,需要两个不同的记录来封装数据 struct stack1*base1,*top1; struct stack2*base2,*top2;//用于建立 int 栈 struct stack1 { int flag;//用于保存优先级 char data;//保存者运算符的变量 struct stack1*next;//提供链接 }; struct stack2 { int number; struct stack2*next; }; struct stack1 *init_stack1()//初始化栈 { struct stack1 *head;//定义栈顶指针 head=(struct stack1*)malloc(SIZE1);//让栈顶指针指向新创建的结点 head->next=NULL; return head;//返回栈的头部 } struct stack2 *init_stack2()//初始化栈 { struct stack2 *head;//定义栈顶指针 head=(struct stack2*)malloc(SIZE2);//让栈顶指针指向新创建的结点 head->next=NULL; return head;//返回栈的头部
} int change(char x) { //用于得出每个运算符的优先级便于进行比较 int flag; switch(x) { } case'#':flag=0;break; case')':flag=1;break; case'+': case'-':flag=2;break; case'*': case'/':flag=3;break; case'(':flag=4;break; return flag; } void push_op(struct stack1 *head,char x) { //让操作符入栈 //当栈空时,直接插入结点,当栈不为空时,在当前栈顶的前面插入一个结点 struct stack1*p; if(head->next==NULL) { p=malloc(SIZE1); p->data=x; p->flag=change(x); printf("%c 已经入栈!\n",x); head->next=p; top1=base1=p; } else//栈不为空 { //在前面插入结点 p=malloc(SIZE1); p->data=x; p->flag=change(x); head->next=p; p->next=top1; top1=p; printf("%c 已经入栈!\n",x); } }
void push_sz(struct stack2 *head,int x) { //让操作符入栈 //当栈空时,直接插入结点,当栈不为空时,在当前栈顶的前面插入一个结点 struct stack2*p; if(head->next==NULL) { p=malloc(SIZE2); p->number=x; printf("%d 已经入栈!\n",x); head->next=p; top2=base2=p; } else//栈不为空 { //在前面插入结点 p=malloc(SIZE2); p->number=x; head->next=p; p->next=top2; top2=p; printf("%d 已经入栈!\n",x); } } char pop1(struct stack1*head) { //将运算符栈顶元素弹出 struct stack1*p; char a; p=top1; a=p->data; head->next=top1->next;//弹出结点 top1=top1->next; free(p); printf("%c 已经从栈中取出!\n",a); return a; } int pop2(struct stack2*head) { //将操作数栈顶元素弹出 struct stack2*p; int a; p=top2; a=p->number;
head->next=top2->next;//弹出结点 top2=top2->next; free(p); printf("%d 已经从栈中取出!\n",a); return a; } void yunsuan(struct stack1*stack_1,struct stack2*stack_2) { //该函数用于进行操作数和运算符的运算 char op; int n1=0,n2=0,result=0; op=pop1(stack_1);//取出运算符 n1=pop2(stack_2);//取出操作数 n2=pop2(stack_2); switch(op) { case'+':result=n1+n2;break; case'-':result=n2-n1;break; case'*':result=n1*n2;break; case'/':result=n2/n1;break; } push_sz(stack_2,result); } int compare(char y[],int number,struct stack1*stack_1,struct stack2*stack_2) { //实现主要的比较操作 int i,j,k;//j 用于保存运算符的优先级 int result; char a[2]; for(i=0;i=48)//说明是字符串中的数字,转换为 int 压入操作数栈 { a[0]=y[i]; a[1]='\0'; k=atoi(a); push_sz(stack_2,k);//入操作符栈 } else//入运算符栈 { if(y[i]=='(')//无需比较将其入栈且下一个运算符也直接入栈 { //实现多括号的运算 push_op(stack_1,y[i]);
i++;//往下走 for(;;i++) { if(y[i]>=48) { a[0]=y[i]; a[1]='\0'; k=atoi(a); push_sz(stack_2,k);//入操作符栈 } else { if(y[i]=='(') push_op(stack_1,y[i]); else { push_op(stack_1,y[i]); break; } } } } else//需要与运算符栈顶元素进行优先级的比较 { j=change(y[i]);//将优先级带出来 if(j==0&&stack_1->next->flag==0)//说明运算结束直接将操作数栈的栈 顶元素弹出 result=pop2(stack_2); break; { } else { if(y[i]==')'&&top1->data=='(')//当两个括号相遇时将其消去 pop1(stack_1); else { if(j>stack_1->next->flag)//优先级高则直接入栈 push_op(stack_1,y[i]); else//优先级小与或者等于栈顶元素时,进行运算 { yunsuan(stack_1,stack_2); i--; }
} } } } } return result; } int main() { struct stack1*stack_1; struct stack2*stack_2; stack_1=init_stack1();//操作数栈的初始化 stack_2=init_stack2();//运算栈的初始化 char x; int num,result=0; x='#'; char y[50]; push_op(stack_1,x); printf("请输入想要计算的表达式(注意括号要用英文括号!):\n"); printf("请用#结尾\n"); gets(y); while(1)//用于控制正确输入 { num = strlen(y); if(y[num-1]=='#') break; else { } printf("输入不规范!请重新输入:\n"); gets(y); } result=compare(y,num,stack_1,stack_2); printf("最后结果为:%d",result); return 0; }
分享到:
收藏