• 栈的应用举例3(表达式求值)


    // func3-2.cpp algo3-6.cpp和algo3-7.cpp要调用的函数
    char Precede(SElemType t1,SElemType t2)
    { // 根据教科书表3.1,判断t1,t2两符号的优先关系('#'用'
    '代替)
    	char f;
    	switch(t2)
    	{
    	case '+':
    	case '-':if(t1=='('||t1=='
    ')
    				 f='<'; // t1<t2
    		else
    			f='>'; // t1>t2
    		break;
    	case '*':
    	case '/':if(t1=='*'||t1=='/'||t1==')')
    				 f='>'; // t1>t2
    		else
    			f='<'; // t1<t2
    		break;
    	case '(':if(t1==')')
    			 {
    				 printf("括号不匹配
    ");
    				 exit(ERROR);
    			 }
    		else
    			f='<'; // t1<t2
    		break;
    	case ')':switch(t1)
    			 {
    	case '(':f='’='; // t1=t2
    		break;
    	case '
    ':printf("缺乏左括号
    ");
    		exit(ERROR);
    	default :f='>'; // t1>t2
    			 }
    		break;
    	case'
    ':switch(t1)
    			 {
    	case'
    ':f='='; // t1=t2
    		break;
    	case'(':printf("缺乏右括号
    ");
    		exit(ERROR);
    	default :f='>'; // t1>t2
    			 }
    	}
    	return f;
    }
    Status In(SElemType c)
    { // 判断c是否为7种运算符之一
    	switch(c)
    	{
    	case'+':
    	case'-':
    	case'*':
    	case'/':
    	case'(':
    	case')':
    	case'
    ':return TRUE;
    	default :return FALSE;
    	}
    }
    SElemType Operate(SElemType a,SElemType theta,SElemType b)
    { // 做四则运算a theta b,返回运算结果
    	switch(theta)
    	{
    	case'+':return a+b;
    	case'-':return a-b;
    	case'*':return a*b;
    	}
    	return a/b;
    }
    // algo3-6.cpp 表达式求值(输入的值在0~9之间,中间结果和输出的值在-128~127之间),算法3.4
    typedef char SElemType; // 栈元素为字符型
    #include"c1.h"
    #include"c3-1.h"
    #include"bo3-1.cpp"
    #include"func3-2.cpp"
    SElemType EvaluateExpression() // 算法3.4,有改动
    { // 算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈
    	SqStack OPTR,OPND;
    	SElemType a,b,c,x;
    	InitStack(OPTR); // 初始化运算符栈OPTR和运算数栈OPND
    	InitStack(OPND);
    	Push(OPTR,'
    '); // 将换行符压入运算符栈OPTR的栈底(改)
    	c=getchar(); // 由键盘读入1个字符到c
    	GetTop(OPTR,x); // 将运算符栈OPTR的栈顶元素赋给x
    	while(c!='
    '||x!='
    ') // c和x不都是换行符
    	{
    		if(In(c)) // c是7种运算符之一
    			switch(Precede(x,c)) // 判断x和c的优先权
    		{
    case'<':Push(OPTR,c); // 栈顶元素x的优先权低,入栈c
    	c=getchar(); // 由键盘读入下一个字符到c
    	break;
    case'=':Pop(OPTR,x); // x='('且c=')'情况,弹出'('给x(后又扔掉)
    	c=getchar(); // 由键盘读入下一个字符到c(扔掉')')
    	break;
    case'>':Pop(OPTR,x); // 栈顶元素x的优先权高,弹出运算符栈OPTR的栈顶元素给x(改)
    	Pop(OPND,b); // 依次弹出运算数栈OPND的栈顶元素给b,a
    	Pop(OPND,a);
    	Push(OPND,Operate(a,x,b)); // 做运算a x b,并将运算结果入运算数栈
    		}
    		else if(c>='0'&&c<='9') // c是操作数
    		{
    			Push(OPND,c-48); // 将该操作数的值(不是ASCII码)压入运算数栈OPND
    			c=getchar(); // 由键盘读入下一个字符到c
    		}
    		else // c是非法字符
    		{
    			printf("出现非法字符
    ");
    			exit(ERROR);
    		}
    		GetTop(OPTR,x); // 将运算符栈OPTR的栈顶元素赋给x
    	}
    	Pop(OPND,x); // 弹出运算数栈OPND的栈顶元素(运算结果)给x(改此处)
    	if(!StackEmpty(OPND)) // 运算数栈OPND不空(运算符栈OPTR仅剩'
    ')
    	{
    		printf("表达式不正确
    ");
    		exit(ERROR);
    	}
    	return x;
    }
    void main()
    {
    	printf("请输入算术表达式(输入的值要在0~9之间、中间运算值和输出结果在-128~127之间)
    ");
    	printf("%d
    ",EvaluateExpression()); // 返回值(8位二进制,1个字节)按整型格式输出
    }
    

    // algo3-7.cpp 表达式求值(范围为int类型,输入负数要用(0-正数)表示)
    typedef int SElemType; // 栈元素类型为整型,改algo3-6.cpp
    #include"c1.h"
    #include"c3-1.h" // 顺序栈的存储结构
    #include"bo3-1.cpp" // 顺序栈的基本操作
    #include"func3-2.cpp"
    SElemType EvaluateExpression()
    { // 算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈
    	SqStack OPTR,OPND;
    	SElemType a,b,d,x; // 改algo3-6.cpp
    	char c; // 存放由键盘接收的字符,改algo3-6.cpp
    	char z[11]; // 存放整数字符串,改algo3-6.cpp
    	int i; // 改algo3-6.cpp
    	InitStack(OPTR); // 初始化运算符栈OPTR和运算数栈OPND
    	InitStack(OPND);
    	Push(OPTR,'
    '); // 将换行符压入运算符栈OPTR的栈底(改)
    	c=getchar(); // 由键盘读入1个字符到c
    	GetTop(OPTR,x); // 将运算符栈OPTR的栈顶元素赋给x
    	while(c!='
    '||x!='
    ') // c和x不都是换行符
    	{
    		if(In(c)) // c是7种运算符之一
    			switch(Precede(x,c)) // 判断x和c的优先权
    		{
    case'<':Push(OPTR,c); // 栈顶元素x的优先权低,入栈c
    	c=getchar(); // 由键盘读入下一个字符到c
    	break;
    case'=':Pop(OPTR,x); // x='('且c=')'情况,弹出'('给x(后又扔掉)
    	c=getchar(); // 由键盘读入下一个字符到c(扔掉')')
    	break;
    case'>' :Pop(OPTR,x); // 栈顶元素x的优先权高,弹出运算符栈OPTR的栈顶元素给x(改)
    	Pop(OPND,b); // 依次弹出运算数栈OPND的栈顶元素给b,a
    	Pop(OPND,a);
    	Push(OPND,Operate(a,x,b)); // 做运算a x b,并将运算结果入运算数栈
    		}
    		else if(c>='0'&&c<='9') // c是操作数,此语句改algo3-6.cpp
    		{
    			i=0;
    			while(c>='0'&&c<='9') // 是连续数字
    			{
    				z[i++]=c;
    				c=getchar();
    			}
    			z[i]=0; // 字符串结束符
    			d=atoi(z); // 将z中保存的数值型字符串转为整型存于d
    			Push(OPND,d); // 将d压入运算数栈OPND
    		}
    		else // c是非法字符,以下同algo3-6.cpp
    		{
    			printf("出现非法字符
    ");
    			exit(ERROR);
    		}
    		GetTop(OPTR,x); // 将运算符栈OPTR的栈顶元素赋给x
    	}
    	Pop(OPND,x); // 弹出运算数栈OPND的栈顶元素(运算结果)给x(改此处)
    	if(!StackEmpty(OPND)) // 运算数栈OPND不空(运算符栈OPTR仅剩’
    ’)
    	{
    		printf("表达式不正确
    ");
    		exit(ERROR);
    	}
    	return x;
    }
    void main()
    {
    	printf("请输入算术表达式,负数要用(0-正数)表示
    ");
    	printf("%d
    ",EvaluateExpression());
    }
    

    algo3-7.cpp运行结果:


  • 相关阅读:
    HD1205吃糖果(鸽巢、抽屉原理)
    POJ3628 Bookshelf 2(01背包+dfs)
    poj1631Bridging signals(最长单调递增子序列 nlgn)
    【转】KMP算法
    Intern Day1
    记 MINIEYE C++应用开发实习生技术一面
    解决Mac下CLion无法编译运行多个cpp的问题
    记赛目科技C++开发工程师实习生技术面
    Git总结
    Docker学习大纲
  • 原文地址:https://www.cnblogs.com/KongkOngL/p/3945964.html
Copyright © 2020-2023  润新知