栈的运用---四则运算

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

思路: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


  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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值