ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-01-12

2021-01-12 21:33:58  阅读:193  来源: 互联网

标签:char 12 01 top 运算符 base 2021 表达式 中缀


实验六 综合设计与应用
表达式求值问题
(1)问题描述
表达式求值是程序设计语言编译中的一个最基本问题。人们在书写表达式时通常采用将
运算符放在两个操作数中间的“中缀”表示形式,称为中缀表达式。但是这种表达式形式对
计算机处理来说是不太适合的。在计算机领域,经常将算术表达式表示成“后缀”表示形式,
称为后缀表达式。如: 中缀表达式 3+2*(7-5)对应的后缀表达式为 3275-+。
表达式是由操作数、运算符、界限符组成的。操作数既可以是常数,也可以是说明为变
量或常量的标示符;运算符可以分为算术运算符、关系运算符和逻辑运算符 3 类;基本界限
符有左右括号和表达式结束符等。
(2)功能与界面要求
要求以字符序列的形式从终端输入或从文件输入语法正确的、不含变量的整数或小数表
达式,并根据输入表达式实现:① 算数四则运算中缀表达式到后缀表达式的转换;② 后缀
表达式的求值;③ 中缀表达式的求值。
要求演示在求值过程中运算符栈、操作数栈、输入字符和主要操作过程及运算结果。
在本题目中可将表达式中的操作数规定为 1 位数字字符。也可根据个人的能力对这部分功能
进行扩充,使得操作数可以是多位数甚至是小数。
算法应该能够过滤掉输入符号之间的空格。也可对本算法功能进行扩充,使其具有对对
输入表达式进行语法检查的功能。
为了简化问题,运算符可只包含+、-、
、/ 四种基本运算,括号只有圆括号。可根据需
要及个人能力对算法的功能进行扩充,允许有其它运算符。
本项目可使用控制台界面或可视化图形界面,若使用可视化图形界面有加分。要求配备
菜单,至少含如下选项:

表达式求值

  1. 中缀表达式到后缀表达式的转换
  2. 后缀表达式的计算
  3. 中缀表达式的计算
  4. 退出

(3)数据结构要求
要求输入表达式采用字符串存储,操作数和运算符采用栈存储,待输出的表达式用队列存储。
(4)算法与数据结构设计指导
①中缀表达式到后缀表达式的转换  问题分析
若一个中缀表达式中没有括号(如 4+23,它的后缀表达式为 423+)。在扫描到中缀表达式中的 2 后,能立即输出+,因为具有较高优先级,必须先运算,因此需先保存+。也就是说,新扫描运算符优先级必须与前一个运算符的优先级做比较,如果新的运算符优先级高,就要像前一个运算符那样保存它,直到扫描到第二个操作数,将它输出后才能将该运算符输出。因此,在转化中必须保存两个运算符,后保存的运算符先输出。用计算机来实现这个转化过程,就需要用到能后进先出的数据结构----栈。
若在中缀表达式中含小括号,那么由于括号隔离了优先级规则,它在整个表达式的内部产生了完全独立的子表达式。因此,前面的算法就需要有所改变。当扫描到一个左括号时,需要将其压入栈中,使其在栈中产生一个“伪栈底”。这样算法就可以像前面一样进行。但当扫描到一个右括号时,需要将栈中从栈顶到“伪栈底”之间的所有运算符弹出,然后再将这个“伪栈底”删除。
 数据结构与算法设计思想
顺序扫描中缀表达式,当读到数字时,直接将其送至输出队列中;当读到运算符时,将运算符栈中所有优先级高于或等于当前运算符的运算符弹出,送至输出队列中,再将当前运算符入栈;当读入左括号时,将其入运算符栈;当读到右括号时,将运算符符栈中从栈顶到靠近栈顶的第一个左括号(“伪栈底”)之间的所有运算符全部依次弹出,送至输出队列中,再删除栈中的左括号。
为了简化算法,可认为扫描到的任何运算符,其优先级都比栈顶的左括号优先级高。为了方便边界条件(栈空)判断,提高算法运行效率,在扫描中缀表达式之前,在空栈中预先
压入一个‘#’字符作为栈底元素,另外,在中缀表达式的最后增加一个‘#’字符作为中缀表达式的结束标志,当扫描到结束符‘#’时,将栈中从栈顶到‘#’之间的所有运算符全部依次弹出,送至输出队列中,再删除栈中的‘#’,并结束算法。
除了显示算法的运行结果外,最好能在算法运行过程中演示运算符栈和存放后缀表达式的队列的变化情况。如,若输入的中缀表达式字符串:1+2
(3-1+2)-3#,就会得到后缀表达式:1231-2+*+3-,在算法运行过程中,运算符栈和存放后缀表达式的队列变化过程如表1所示。
表一
代码如下

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define TTACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef struct{
	float *base;
	float *top;
	int stacksize;
}SqStack_f;
typedef struct{
	char *base;
	char *top;
	int stacksize;
}SqStack_c;
void InitStack_f(SqStack_f *s)
{
	s->base=(float *)malloc(TTACK_INIT_SIZE*sizeof(float));
	if(!s->base)
		exit(1);
	s->top=s->base;
	s->stacksize=TTACK_INIT_SIZE;
}
void InitStack_c(SqStack_c *s)
{
	s->base=(char *)malloc(TTACK_INIT_SIZE*sizeof(char));
	if(!s->base)
		exit(1);
	s->top=s->base;
	s->stacksize=TTACK_INIT_SIZE;
}
void GetTop_f(SqStack_f *s,float *e)
{
	if(s->top==s->base)
	{
		printf("ERROR!\n");
		exit(1);
	}
	*e=*(s->top-1);
}
void GetTop_c(SqStack_c *s,char *e)
{
	if(s->top==s->base)
	{
		printf("ERROR!\n");
		exit(1);
	}
	*e=*(s->top-1);
}
void Push_f(SqStack_f *s,float e)
{
	if(s->top-s->base>=s->stacksize)
	{
		s->base=(float *)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(float));
		if(!s->base)
		{
			printf("OVERFLOW!\n");
			exit(1);
		}
		s->top=s->base+s->stacksize;
		s->stacksize+=STACKINCREMENT;
	}
	*s->top++=e;
}
void Push_c(SqStack_c *s,char e)
{
	if(s->top-s->base>=s->stacksize)
	{
		s->base=(char *)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(char));
		if(!s->base)
		{
			printf("OVERFLOW!\n");
			exit(1);
		}
		s->top=s->base+s->stacksize;
		s->stacksize+=STACKINCREMENT;
	}
	*s->top++=e;
}
void Pop_f(SqStack_f *s,float *e)
{
	if(s->top==s->base)
		exit(1);
	*e=*--s->top;
}
void Pop_c(SqStack_c *s,char *e)
{
	if(s->top==s->base)
		exit(1);
	*e=*--s->top;
}
int precede(char Top_char,char s1_char)
{
	int i,pre[2];
	char op[2];
	op[0]=Top_char;
	op[1]=s1_char;
	for(i=0;i<2;i++)
		switch(op[i])
		{
		case'(':case')':pre[i]=0;break;
		case'+':case'-':pre[i]=1;break;
		case'*':case'/':pre[i]=2;break;
		case'^':pre[i]=3;break;
		}
	if(pre[0]>=pre[1])
		return 1;
	else
		return 0;
}
void Translate(char *s1)
{
	char s2[80];
	SqStack_c Optr;
	int i=0,j=0;
	char t;
	InitStack_c(&Optr);
	Push_c(&Optr,'(');
	while(s1[i]!='#')
	{
		if(s1[i]>='0' && s1[i]<='9' || s1[i]=='.')
		{
			s2[j++]=s1[i];
			if((s1[i+1]<'0' || s1[i+1]>'9') && s1[i+1]!='.')
				s2[j++]=' ';
		}
		else
			switch(s1[i])
		{
			case'(':Push_c(&Optr,s1[i]);break;
			case')':Pop_c(&Optr,&t);
				while(t!='(')
				{
					s2[j++]=t;
					Pop_c(&Optr,&t);
				}
				break;
			default:while(GetTop_c(&Optr,&t),precede(t,s1[i]))
					{
						Pop_c(&Optr,&t);
						s2[j++]=t;
					}
				Push_c(&Optr,s1[i]);
		}
		i++;
	}
	Pop_c(&Optr,&t);
	while(t!='(')
	{
		s2[j++]=t;
		Pop_c(&Optr,&t);
	}
	for(i=0;i<j;i++)
		s1[i]=s2[i];
	s1[i]='#';s1[i+1]='\0';
} 
void Calculate(SqStack_f *s,char *s2)
{
	float m,x,y,z;
	int i=0,j=0;
	while(s2[i]!='#')
	{
		if(s2[i]>='0' && s2[i]<='9' || s2[i]=='.')
		{
			m=0;
			while(s2[i]!=' ' && s2[i]!='.')
				m=m*10+(float)(s2[i++]-'0');
			if(s2[i]=='.')
			{
				j=0;i++;
				while(s2[i]!=' ')
				{
					m=m*10+(float)(s2[i++]-'0');
				    j++;
				}
			while(j>0)
			{
				m/=10;
				j--;
			}
			}
			i++;
		    Push_f(s,m);
		    GetTop_f(s,&m);
		    printf("The result is:%g\n",m);
		}
		else
		{
			Pop_f(s,&x);
			Pop_f(s,&y);
			switch(s2[i])
			{
			case '+':z=y+x;printf("The result is:%g\n",z);break;
			case '-':z=y-x;printf("The result is:%g\n",z);break;
			case '*':z=y*x;printf("The result is:%g\n",z);break;
			case '/':if(x==0)
					 {
						 printf("表达式出错,除数为‘0’,无意义\n");
						 exit(1);
					 }
				else
				{
					z=y/x;
					printf("The result is:%g\n",z);break;
				}
			case '^':z=1;for(j=1;j<=x;j++)
					 {
						 z=z*y;
						 printf("The result is:%g\n",z);
					 }
			}
			Push_f(s,z);
			i++;
		}
	}
}
void result(SqStack_f *s)
{
	float v;
	GetTop_f(s,&v);
	printf("The final result is:%g\n",v);
}
int main()
{
	SqStack_f stack;
	char str[80],c='Y';
	while(c=='y' || c=='Y')
	{
		printf("输入表达式,以#结尾\n");
	    gets(str);
	    InitStack_f(&stack);
	    Translate(str);
	    printf("转化后的后缀表达式为:\n");
	    puts(str);
	    Calculate(&stack,str);
	    result(&stack);
	    c=getchar();
		getchar();
	}
}

标签:char,12,01,top,运算符,base,2021,表达式,中缀
来源: https://blog.csdn.net/weixin_51529474/article/details/112547952

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有