zoukankan      html  css  js  c++  java
  • codeup 1743: 算法3-4:表达式求值

    1743: 算法3-4:表达式求值

    题目描述

    算数四则运算的规则是1)先乘除,后加减;2)从左算到右;3)先括号内,后括号外。
    由此,算式4+2*3-10/5的计算顺序为4+2*3-10/5=4+6-10/5=4+6-2=8。
    给定一个以“#”作为结束符的算式,求出算式的结果。
    给出严蔚敏《数据结构(C语言)》中的一段算法描述以作参考:
    图1:表达式求值算法
    图2:表达式求值算法(续)

    3:表达式求值算法(续)

    输入

    以“#”结尾的表达式,运算数为正整数。每个表达式占一行。

    输出

    输出表达式运算的结果。

    样例输入

    4+2*3-10/5#
    3*(7-2)#
    2*3/2#

    样例输出

    8
    15
    3

    置运算符栈为空栈,表达式的起始符'#'为栈底元素

    依次读入表达式的每个字符,若是操作数则进OPND栈,若是运算符O则和OPTR栈的栈顶元素比较优先权后进行相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为'#').
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    
    #define N 1000+10
    #define STACK_INIT_SIZE 100
    #define STACKINCREMENT 10
    #define OK 1
    #define OVERFLOW 0
    #define ERROR 0
    
    char str[N];
    typedef  int Status;
    typedef  int SElemType;
    
    typedef struct{
    	SElemType *base;
    	SElemType *top;
    	int stacksize;
    }SqStack;
    
    unsigned char prior[7][7] = {
    {'>','>','<','<','<','>','>'},
    {'>','>','<','<','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'<','<','<','<','<','=',' '},
    {'<','<','<','<','<',' ','>'},
    {'<','<','<','<','<',' ','='}};
    
    char OPSET[7] = {'+','-','*','/','(',')','#'};
    
    Status InitStack(SqStack *s)//初始化栈 
    {
    	s->base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    	if(!s->base)
    		exit(OVERFLOW);
    	s->top = s->base ;
    	s->stacksize = STACK_INIT_SIZE;
    	return OK;
    }
    
    Status Push(SqStack *s,SElemType c)//入栈 
    {
    	if((s->top - s->base ) >= s->stacksize )
    	{
    		s->base = (SElemType*)realloc(s->base ,(s->stacksize +STACKINCREMENT)*sizeof(SElemType));
    		if(!s->base )
    			exit(OVERFLOW);
    		s->stacksize += STACKINCREMENT;
    	}
    	*(s->top)++ = c;
    	return OK;
    }
    
    Status GetTop(SqStack *s)//取栈顶元素 
    {
    	SElemType e;
    	if(s->base == s->top )
    		return ERROR;
    	e = *(s->top-1)    ;
    	return e;
    }
    
    Status In(char c,char str[])//判断是否为运算符 
    {
    	int i = 0;
    	while(c != str[i])
    	{
    		i++;
    	}
    	if(i < 7)
    		return OK;
    	return ERROR;
    }
    
    void  Strcat(char *str1,char *str2)//字符串连接函数,把字符串str2连接到str1后 
    {
    	int i = 0, j = 0;
    	while(str1[i]!='')
    	{
    		i++;
    	}
    	while(str2[j]!='')
    	{
    		str1[i++] = str2[j++];
    	}
    	str1[i] = '';
    } 
    
    Status Atoi(char *c)//把字符串转为数字 
    {
    	int data= 0,d = 0;
    	int i = 0;
    	while(c[i]!='')
    	{
    		data = data*10 + c[i]-'0';
    		i++;
    	}
    	return data;	
    } 
    
    Status precede(int a,char b)//判断优先级函数 
    {
    	int i = 0,j = 0;
    	while(OPSET[i] != a)
    	{
    		i++;
    	}
    	while(OPSET[j] != b)
    	{
    		j++;
    	}
    	return prior[i][j];
    }
    
    Status Pop(SqStack *s)//脱括号函数 
    {
    	int e;
    	if(s->base == s->top )
    		return ERROR;
    	e = *--(s->top);
    	return e;
    }
    
    Status Opereta(int a,int b,int c)//运算函数 
    {
    	switch(b)
    	{
    		case '+':
    			return a+c;
    		case '-':
    			return a-c;
    		case '*':
    			return a*c;
    		case '/':
    			return a/c;
    	} 
    }
    
    int EvaluateExpression(char *MyExpression)//算法3.4 
    {//算术表达式求值的算符优先算法。
    //设OPTR和OPND分别为运算符栈和运算数栈
    	SqStack OPTR;//运算符栈,字符元素 
    	SqStack OPND;//运算数栈,实数元素 
    	
    	char TempData[20];
    	int data,a,b;
    	char *c,Dr[2],e;
    	int theta;
    	
    	InitStack(&OPTR);
    	Push(&OPTR,'#');
    	InitStack(&OPND);
    	
    	c = MyExpression;
    	TempData[0] = '';
    	while(*c != '#'|| GetTop(&OPTR) != '#')
    	{
    		
    		if(!In(*c,OPSET))//不是运算符则进栈 
    		{
    			Dr[0] = *c;
    			Dr[1] = '';
    			Strcat(TempData,Dr);
    			c++; 
    			if(In(*c,OPSET))//是运算符时 
    			{
    				data = Atoi(TempData);
    				Push(&OPND,data);
    				TempData[0] = '';
    			}
    		}
    		else
    		{
    			switch(precede(GetTop(&OPTR),*c))
    			{
    				case '<':
    					Push(&OPTR,*c);
    					c++;
    					break;
    				case '=':
    					Pop(&OPTR);
    					
    					c++;
    					break;
    				case '>':
    					a = Pop(&OPND);
    					b = Pop(&OPND);
    					theta = Pop(&OPTR);
    					Push(&OPND,Opereta(b,theta,a));
    					break;
    			}
    		}
    	}
    	
    	return GetTop(&OPND);
    }
    int main()
    {
    	
    	while(scanf("%s",str)!=EOF)
    	{
    		printf("%d
    ",EvaluateExpression(str));
    	}
    	return 0;
     } 



  • 相关阅读:
    理解java的三大特性之封装
    Spring_事务-注解代码
    Spring_使用 NamedParameterJdbcTemplate
    C#多线程简单例子讲解
    C#多线程编程
    ASP.NET MVC 的URL路由介绍
    NHibernate二级缓存(第十一篇)
    NHibernate之配置文件属性说明
    NHibernate之映射文件配置说明
    NHibernate 延迟加载与立即加载 (第七篇)
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7350124.html
Copyright © 2011-2022 走看看