栈的运用---四则运算

来源:互联网 发布:mac限免软件 编辑:程序博客网 时间:2024/05/16 13:58

四则运算---用栈实现一下。

思路:1.得有一串字符串,-----》给定中缀;6+(7-1)*3+8.8/2 

           2.转换中缀为后缀:6 7 1 - 3 * + 8.8 2 / +

           3.变成后缀后,就不用看看+-*/()导致的运算级优先级。

                 ADD_OUT = 4,
         SUB_OUT =  4,
         MUL_OUT = 6,
         DIV_OUT =  6,
         LEFT_OUT = 10,
         RIGHT_OUT = 1,
         ADD_IN  =  5,
         SUB_IN  =  5,
         MUL_IN  =  7,
         DIV_IN  =  7,
         LEFT_IN =  1,
        RIGHT_IN = 1

        代码:

        ARITH.h

#ifndef _ARITH_H_#define _ARITH_H_#define IN 0#define OUT 1typedef float elem_type;//如果想换个类型,记得吧LINK_STACH.h里面的也改掉typedef elem_type (*pfun)(elem_type,elem_type);elem_type add_a(elem_type p,elem_type e);elem_type sub_a(elem_type p,elem_type e);elem_type mul_a(elem_type p,elem_type e);elem_type div_a(elem_type p,elem_type e);typedef enum _ARIT{ADD = '+',    SUB = '-',MUL='*',DIV = '/'}ARIT;typedef struct _CHOSE_BY{ ARIT symbol;    pfun func;}CHOSE_BY;typedef enum _PRI0//符号优先级的处理{ADD_OUT = 4,SUB_OUT =  4,MUL_OUT = 6,DIV_OUT =  6,LEFT_OUT = 10,RIGHT_OUT = 1,ADD_IN  =  5,SUB_IN  =  5,MUL_IN  =  7,DIV_IN  =  7,LEFT_IN =  1,RIGHT_IN = 1}PRI0; elem_type get_res(char *str);void get_last(char *str1,char *str2);#endif


  ARITH.cpp

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>#include "ARITH.h"#include "LINK_STACK.h"CHOSE_BY chose_way[] = {{ADD,add_a},{SUB,sub_a},{MUL,mul_a},{DIV,div_a},};elem_type add_a(elem_type p,elem_type e){return p + e;}elem_type sub_a(elem_type p,elem_type e){return p-e;}elem_type mul_a(elem_type p,elem_type e){return p*e;}elem_type div_a(elem_type p,elem_type e){if(e == 0){printf("在运算中有个除数是0\n");exit(-1);}return p/e;}elem_type get_res(char *str)//数字入栈{    LINKSTACH *p = init_stack();char buff[20] = {0};int j = 0;elem_type op1 = 0;elem_type op2 = 0;if(str == NULL){return false;}while(*str != 0){j = 0;if(*str == '+' ||*str == '-' ||*str == '*' ||*str == '/'){if(!is_empty(p)){pop(p,&op2);pop(p,&op1);for(int i = 0;i < sizeof(chose_way)/sizeof(chose_way[0]); i ++){if( *str == chose_way[i].symbol){op1 = chose_way[i].func(op1,op2);push(p,op1);break;}}}else{printf("你的后缀表达式有误\n");exit(-1);}}else if(*str == ' '){;}else if(*str >= '0' && *str <= '9'){ while(*str != ' ') { buff[j++] = *str; str++; } str --;// char arr[20] = "elem_type"; int len = strlen(buff); bool flag = true; for(int k = 0;k < len ; k ++) { if(buff[k] == '.') { elem_type f = atof(buff); push(p ,f); flag = false; break; } } if(flag) { elem_type  d= atoi(buff);      push(p ,d); }strset(buff,0);}else{printf("你的后缀表达式有误\n");exit(-1);}str ++;}pop(p,&op1);if(is_empty(p)){return op1;}else{printf("你的后缀表达式有误\n");exit(-1);}destroy_stack(p);}/*   遇到数字存放在str2中,+ - * / 进栈   原则: 栈外的想进栈,站内的想出栈。谁强听谁的        1.栈外》栈内  ,入栈         2.栈外《栈内  ,栈内出栈,P不动 3.一样,屏蔽括号*/static int get_prio_num(char ch,int state) //获取优先级的数值{if(state == OUT){switch(ch){case '+':return ADD_OUT;case '-':return SUB_OUT;case '*':return MUL_OUT;case '/':return DIV_OUT;case '(':return LEFT_OUT;case ')':return RIGHT_OUT;default:return ERROR;}}else{switch(ch){case '+':return ADD_IN;case '-':return SUB_IN;case '*':return MUL_IN;case '/':return DIV_IN;case '(':return LEFT_IN;case ')':return RIGHT_IN;default:return ERROR;}}}void get_last(char *str1,char *str2)//str1存储的是中缀表达式  str2存储的是后缀表达式{LINKSTACH *p = init_stack();int j = 0;elem_type op1 = 0;elem_type op2 = 0;char buff[10] = {0};if(str1 == NULL || str2 == NULL){return ;}while(*str1 != 0){j = 0;if(*str1 == '+' ||*str1 == '-' ||*str1 == '*' ||*str1 == '/'||*str1 == '(' ||*str1 == ')'){if(is_empty(p)){                push(p,*str1);}else{get_top(p,&op2);int val = get_prio_num(*str1,OUT);int val2 = get_prio_num(op2,IN);if(val > val2)//栈外的 > 栈内的  ---入栈{push(p,*str1);}else if(val == val2)//栈外的 == 栈内的  ---抵消(左右括号){pop(p,&op1);}else//栈外的 < 栈内的  ---出栈{pop(p, &op1);*str2 = op1;str2++;*str2 = ' ';str2++;str1 --;}}}else if(*str1 == ' '){;}else if(*str1 >= '0' && *str1 <= '9' || *str1 == '.'){while(*str1 >= '0' && *str1 <= '9' || *str1 == '.' ){*str2++ = *str1++;}*str2 = ' ';str1 --;str2++;}else{printf("你的中缀表达式有误\n");exit(-1);}str1 ++;}while(!is_empty(p)){pop(p, &op1);*str2 = op1;str2++;*str2 = ' ';str2++;}}

MAIN.c

#include<stdio.h>#include "ARITH.h"int main(){//char mid_str[100] = "6+(7-1)*3+8.8/2";22+70-21/4+(3-1)*(8/2)char mid_str[100] = "22+70-21/4+(3-1)*(8/2)";char last_str[100]  = {0};//"6 7 1 - 3 * + 8.8 2 / +";get_last(mid_str,last_str);elem_type va = get_res(last_str);//printf("%s",last_str);printf("%lf\n",va);return 0;}
在这里面,你都会遇到LINK_STACK 所以,你得引进来,LINK_STACK.H和LINK_STACK.cpp


http://blog.csdn.net/qq_35256722/article/details/52915814


0 0