栈结构实现表达式求值

目录

1、内容描述需求分析:

2、数据结构定义:

3、主程序的流程及各程序模块之间的调用关系。

4、代码实现演示:

5、各模块之间的调用关系:


 下方有源码解析 噢 !

1、内容描述需求分析:

(1)输入的形式和输出值的范围;

输入的形式:数学运算表达式例如:3*(34-23)+5=;

输出的范围:int型的整数目前暂时不支持double型的数值。

2输出的形式;

输出的形式:输出表达式以及结果。例如:3*(34-23)+5=38;

(3)程序所能达到的功能;

功能:进行数学表达式的运算,且支持多层括号的表达式的运算

2、数据结构定义:

(1)确定数据对象及结构

本实验是线性表的栈的顺序存储结构,通过函数InitStack初始化创建了两个max(100)大小的栈(一个为int型的数字栈,一个为为了存储运算符(+,-,*,/等运算符)的栈)

(2)存储结构的选择和定义:需要说明本实验采用了什么存储结构,并给出对应程序中的定义,例如,线性表采用了顺序存储结构,可以用以下程序来定义:

首先本实验我采用的是顺序存储结构,起初采用顺序存储的原因是用栈来实现表达式的运算进出栈比较频繁,用顺序存储可能比较方便,以下就是栈的抽象数据类型的定义:

#define max 100

typedef struct Student{

 int *base;

 Int*top;

Int stacksize;

}

3主程序的流程及各程序模块之间的调用关系。

(1)根据实验内容确定需要实现的全部函数。

InitStack(Stack &s)栈的初始化;

push(Stack &s,int e):将数据e入栈;

pop(Stack &s,int &e):出栈,并通过e返回;

Gettop(Stack s):返回栈顶元素;

ifpriority(char the1,char the2):比较运算符the1与the2的优先级大小,the1为获得的栈顶元素,the2为输入的(将要入栈的)字符,如果the2的优先级较大则入栈,否者,the1则出栈并从数字栈中出栈两个元素进行运算,之后再将运算的结果入栈;

ifoperators(char ch):判断字符ch是否为算数运算符;

ifnumber(char ch):判断字符是否为数字;

maths(int first,char the,int second):接上ifpriority函数进行运算的函数;

text(char operout[]):此函数就是用来进行最后的测试程序的函数,首先在主函数中定义一个operatorout[100]字符数组用以输入表达式,将数组传入text函数中,再进行索引一个一个判断是运算符还是数字,进行入栈或者出栈。

4、代码实现演示:

代码的乐趣:好好学习@@@

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define OK 1
#define max 100
//(1) 使用栈结构实现表达式求值
typedef struct Student{
   int *base;
   int *top;
   int stacksize;
}Stack,*Stack1;
char ifoperator[7]={'+' , '*' , '-' , '/' , '(' , ')' , '='};
//栈的初始化
bool InitStack(Stack &s){
	s.base = new int[max];
	if(!s.base) {
		printf("初始化栈失败!");
		exit(0);
	}
	s.top = s.base;
	s.stacksize = max;
	return OK;
}
//入栈
bool push(Stack &s,int e){
	if(s.top-s.base==s.stacksize) return 0;
	*s.top++=e;
//或者为
//	*s.top=e;
//	s.top++; 
	return OK;
} 
//出栈
bool pop(Stack &s,int &e){
	if(s.base==s.top) {
	  printf("栈中为空!");
	  return 0;
	}
	e = *--s.top;
	//或者为
//	s.top--;
//	e=*s.top;
	return OK;
} 
//获取栈顶元素
int Gettop(Stack s){
	if(s.top!=s.base) 
	return *(s.top-1);
} 
//判断运算符优先级
//还可以将优先级表的先后顺序写入一个二维数组中来判断 ,见与栈的练习2,23行 
char ifpriority(char the1,char the2){
	if((the1=='(' && the2==')'||(the1=='=' && the2=='='))){
		return '=';
	}else if(the1=='('||the1=='='||the2=='('||(the1=='+'||the1=='-')&&(the2=='*'||the2=='/')){
		return '<';
	}else
	return '>';
} 
//判断是否为算符
bool ifoperators(char ch){
	for(int i=0;i<7;i++){
		if(ch==ifoperator[i]){
			return true;
		}
	} 
	return false;
}  
//判断是否是数字
bool ifnumber(char ch){
	if(ch>='0'&&ch<='9'){
		return true;
	}
	return false;
} 
//计算运算的结果
int maths(int first,char the,int second){
switch(the){
	case '+':
		return first+second;
	case '-':
		return first-second;
	case '*':
		return first*second;		
	case '/':
		return first/second;	
    }
		return 0;
} 
//
int text(char operout[]){
	Stack oper1,number1;
	int x0,x,x1,x2,x3,a,b,the;
	char ch;
	int i=0;
	InitStack(number1);
	InitStack(oper1);
	push(oper1,'=');
	ch = operout[i++];
	while(ch!='='||Gettop(oper1)!='='){
		if(ifoperators(ch)){
			switch(ifpriority(Gettop(oper1),ch)){
             case '<':
			 push(oper1,ch);
			 ch = operout[i++];
			 break;
			 case '>':
			 pop(oper1,the);
			 pop(number1,b);
			 pop(number1,a);
			 push(number1,maths(a,the,b));
			 break;
			 case '=':
             	pop(oper1,x);
				ch = operout[i++];
			 break;				
			}
		}else if(ifnumber(ch)){	
		    x1=ch-'0';
			push(number1,x1);
			x2=x1;
			ch = operout[i++];
			while(ifnumber(ch)){
			       x1=ch-'0';
			       x2=10*x2+x1;
			       pop(number1,x);
				   push(number1,x2); 
				   ch = operout[i++];
			}
		}else if(ch==' '){
			while(ch==' '){
				ch==operout[i++];
			}
		}else{
			printf("为不规则运算符或表达式格式输入错误!!");
			exit(0); 
		}
	}
	return (Gettop(number1));
}
int main(){
	char operatorout[100]; 
	int result,r=0;
	while(true){
	printf("输入1为计算表达式 2为退出计算:\n");
	scanf("%d",&r); 
	switch(r){
		case 1:
             printf("请输入你将要求解的表达式:格式为(数表达式=):\n");
             printf("表达式格式为:目前仅支持整数的加减乘除运算且可以加入多层运算(多括号)例:(())\n"); 
          //gets(operatorout);
             scanf("%s",operatorout); 
        	result = text(operatorout);
        	printf("运算结果为:");
         	printf("%s%d\n",operatorout,result);
//         	system("pause");
//         	system("cls");
		break;
		case 2:
			exit(0);
			system("pause");
		break;
		default:
        printf("输入错误请重新输入:");		
		break;
    	} 
	}
	return 0;
}

5、各模块之间的调用关系:

博主制作文章需要付出巨大的努力和心血制作不易!!如果对你有帮助的话 不妨点个赞噢!
博主渴望读者的关注和赞赏,因为这是对他们辛勤工作的最好认可和鼓励。

博主希望读者能够欣赏他们的专业知识和独到见解,同时也希望读者能够积极参与讨论,分享自己的看法和经验。
无论是通过点赞、评论还是分享,读者的支持对于博主们来说都是极为重要的。这些肯定和鼓励将激励博主们更加努力地创作出更多有价值的内容,为读者提供实用的技术指导和行业见解。
所以,如果你喜欢博主的文章,不妨给他们一点关注和赞赏吧!你的支持将成为他们创作的动力,也会让他们更加热情地为你带来更多精彩的内容。

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值