四则运算---用栈实现一下。
思路: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 1
typedef 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
#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