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;
     } 



  • 相关阅读:
    vue开发chrome扩展,数据通过storage对象获取
    Vue手动集成less预编译器
    Google Translate寻找之旅
    Javascript Range对象的学习
    Javascript Promises学习
    SublimeText 建立构建Node js系统
    We're sorry but demo3 doesn't work properly without JavaScript enabled. Please enable it to continue.
    npm安装包出现UNMET DEPENDENCY报错
    (转载)命令行说明中格式 尖括号 中括号的含义
    Linux重启网卡服务Failed to start LSB: Bring up/down networking.
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7350124.html
Copyright © 2011-2022 走看看