欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C/C++ 小程序:表达式计算器

程序员文章站 2024-03-19 08:59:52
...

项目简介:

------本程序用来计算运算数与运算结果都在0-10这个范围内的算式,支持加减乘除的计算。小编用两种方法编写了这个程序:

  • 自己定义栈的结构体,这种方法把栈用数组表示,不需要指针,栈顶指针top直接用数组的下标表示,比较简单,比较适用于初学栈,初学C语言,想要练习的小白,方便实现,简单易懂。
  • 直接用C++的stack栈类型:要想实现这个方法,需要对C++有基本的了解,会C++的人,很容易实现,如果没有接触过C++或者是略懂C++的同志们,略微看一下我的注释,也是可以理解的。

算法步骤:

① 初始化OPTC栈和OPTN栈,将表达式起始符“#”压入OPTC栈。
② 扫描表达式,读入第一个字符ch,如果表达式没有扫描完毕至“#”或OPTR的栈顶元素不为“#”时,则循环执行以下操作:

  • 若ch不是运算符,则压入OPTN栈,读入下一字符ch;
  • 若ch是运算符,则根据OPTC的栈顶元素和ch的优先级比较结果,做不同的处理:
    A、若是栈OPTC的栈顶元素优先级小于ch,则ch压入OPTC栈,读入下一字符ch;
    B、若是栈OPTC的栈顶元素优先级大于ch,则弹出OPTC栈顶的运算符,从OPTN栈弹出两个数,进行相应运算,结果压入OPTN栈;
    C、若是栈OPTC的栈顶元素优先级等于ch,则OPTC的栈顶元素是“(”且ch是“)”,这时弹出OPTC栈顶的“(”,相当于括号匹配成功,然后读入下一字符ch。

③ OPTN栈顶元素即为表达式求值结果,返回此元素。

关于符号之间的优先级:下图是不同符号之间的优先级关系

程序在进行运算的时候,按照从左到右的顺序从输入的字符串中读入运算数或运算符,在这里符号1指的是两个符号中左边的那个符号,符合二指的是右边的那个符号。如果是>,则先对运算符1进行计算,再对运算符2进行计算;如果是=,则脱括号(这个地方,在程序中有解释,就是直接将左括号从运算符栈中弹出);如果是×,则表示算式读入完成。
C/C++ 小程序:表达式计算器

算法流程图:

C/C++ 小程序:表达式计算器

方法一:自定义结构体栈:

#include <bits/stdc++.h>
using namespace std;
/*----------------宏定义-------------------*/
#define MAXSIZE 100

/*----------------定义栈-------------------*/
typedef struct {           //定义栈
	char a[MAXSIZE];
	int  top;
} cStack;

/*----------------全局变量-------------------*/
char op[7]= {'+','-','*','/','(',')','#'};

char relation[7][7]= {    //定义运算符之间的优先级关系
	{'>','>','<','<','<','>','>'},
	{'>','>','<','<','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'<','<','<','<','<','=',' '},
	{'>','>','>','>',' ','>','>'},
	{'<','<','<','<','<',' ','='}
};

/*----------------入栈函数-------------------*/
void Push(cStack &zhan,char i) {
	zhan.a[zhan.top]=i;
	zhan.top++;
}

/*----------------获取栈顶元素函数-------------------*/
char getTop(cStack &zhan) {
	int i=zhan.top-1;
	return zhan.a[i];
}

/*----------------出栈函数-------------------*/
void Pop(cStack &zhan,char &i) {
	zhan.top--;
	i=zhan.a[zhan.top];
}

/*----------------运算函数-------------------*/
char Operate(char a,char o,char b) {
	int x=a-'0';
	int y=b-'0';
	int result;
	switch(o) {
		case'+':
			result=x+y;
			break;
		case'-':
			result=x-y;
			break;
		case'*':
			result=x*y;
			break;
		case'/':          //注意分母不能是0的情况
			if(y==0) {
				cout<<"分母为0!";
				return  0;
			} else {
				result=x/y;
				break;
			}
		default:
			cout<<"请输入正确的运算符!";
			printf("%c",o);
			break;
	}
	return '0'+result;
}
/*----------------判断ch是否为运算符-------------------*/
int in(char ch) {
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#') return 1;
	else return 0;
}

/*----------------比较运算符优先级函数-------------------*/
char Compare(char j,char k) {
	int x,y;
	switch(j) {
		case'+':
			x=0;
			break;
		case'-':
			x=1;
			break;
		case'*':
			x=2;
			break;
		case'/':
			x=3;
			break;
		case'(':
			x=4;
			break;
		case')':
			x=5;
			break;
		case'#':
			x=6;
			break;
	}
	switch(k) {
		case'+':
			y=0;
			break;
		case'-':
			y=1;
			break;
		case'*':
			y=2;
			break;
		case'/':
			y=3;
			break;
		case'(':
			y=4;
			break;
		case')':
			y=5;
			break;
		case'#':
			y=6;
			break;
	}
	return relation[x][y];
}

/*----------------主函数-------------------*/
int main() {
	int b=1;
	while(b) {
		cStack OPTC,OPTN;
		OPTC.top=0;                                  //初始化运算符栈
		OPTN.top=0;                                  //初始化运算数栈
		cout<<"请输入您要计算的算式:";
		Push(OPTC,'#');
		char ch,a,o,b,n;
		ch=getchar();
		while(ch!='#'||getTop(OPTC)!='#') {         //因为只有当ch=='#'&&getTop(OPTC)=='#'成立时才终止循环,输出运算结果;
			if(in(ch)==0) {                         //如果ch不是运算符,则进入运算数栈OPTN
				Push(OPTN,ch);
				ch=getchar();
			} else {
				switch(Compare(getTop(OPTC),ch)) {  //比较符号栈栈顶元素与ch的优先级
					case'<':
						Push(OPTC,ch);          //如果符号栈栈顶元素的优先级小于ch,就将ch压入运算符栈OPTC
						ch=getchar();
						break;
					case'>':
						Pop(OPTC,o);           //如果符号栈栈顶元素的优先级大于ch,就弹出运算符栈OPTC的栈顶指针,并弹出两个运算数,进行计算,将计算结果压入运算数栈
						Pop(OPTN,b);
						Pop(OPTN,a);
						Push(OPTN,Operate(a,o,b));
						//ch=getchar();          //不需要再读入一个,因为刚才读进来的那个还没用,用的这个是从栈里出来的
						break;
					case'=':
						Pop(OPTC,n);            //如果相等,脱括号
						ch=getchar();
						break;
				}
			}
		}
		cout<<"最终运算结果为:";
		cout<<getTop(OPTN)<<endl;
		cout<<"请问您是否需要继续计算?(1.继续 0.退出)";
		cin>>b; 
	}
	return 0;
}

方法二:直接用C++提供的stack栈类型:

#include <bits/stdc++.h>
using namespace std;
/*----------------全局变量-------------------*/
char op[7]= {'+','-','*','/','(',')','#'};
char relation[7][7]= {                     //定义运算符之间的优先级关系
	{'>','>','<','<','<','>','>'},
	{'>','>','<','<','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'<','<','<','<','<','=',' '},
	{'>','>','>','>',' ','>','>'},
	{'<','<','<','<','<',' ','='}
};
/*----------------运算函数-------------------*/
char Operate(char a,char o,char b) {
	int x=a-'0';
	int y=b-'0';
	int result;
	switch(o) {
		case'+':
			result=x+y;
			break;
		case'-':
			result=x-y;
			break;
		case'*':
			result=x*y;
			break;
		case'/':          //注意分母不能是0的情况
			if(y==0) {
				cout<<"分母为0!";
				return  0;
			} else {
				result=x/y;
				break;
			}
		default:
			cout<<"请输入正确的运算符!";
			printf("%c",o);
			break;
	}
	return '0'+result;
}
/*----------------判断ch是否为运算符-------------------*/
int in(char ch) {
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#') return 1;
	else return 0;
}
/*----------------选择符号函数-------------------*/
int Switch(char i){
	switch(i) {
		case'+':
		    return 0;
		case'-':
			return 1;
		case'*':
			return 2;
		case'/':
			return 3;
		case'(':
			return 4;
		case')':
			return 5;
		case'#':
			return 6;
	}
} 
/*----------------比较运算符优先级函数-------------------*/
char Compare(char j,char k) {
	int x,y;
	x=Switch(j);
	y=Switch(k); 
	return relation[x][y];
}
/*----------------主函数-------------------*/
int main() {
	int flag=1;
	cout<<"注意:本计算机支持+、-、*、/运算,且只能进行运算数与运算结果在0-10这个范围内的算式," <<endl;
	cout<<"      ()必须是英文的(),算式末尾需要加上一个#,以表示算式输入结束,输入格式示例:1+2*(4/2)# "<<endl; 
	while(flag!=0) {
		stack<char> OPTC,OPTN;                      //调用C++中的栈 
		cout<<"请输入您要计算的算式:";
		OPTC.push('#');                             //向运算符栈中压入'#' 
		char ch,a,o,b,n;
		ch=getchar();
		while(ch!='#'||OPTC.top()!='#') {          //因为只有当ch=='#'&&getTop(OPTC)=='#'成立时才终止循环,输出运算结果;所以当ch!='#'||OPTC.top()!='#'时,可以一直读入输入的算式进行计算 
			if(in(ch)==0) {                        //如果ch不是运算符,则进入运算数栈OPTN
				OPTN.push(ch);
				ch=getchar();
			} else {
				switch(Compare(OPTC.top(),ch)) {   //比较符号栈栈顶元素与ch的优先级
					case'<':
						OPTC.push(ch);             //如果符号栈栈顶元素的优先级小于ch,就将ch压入运算符栈OPTC
						ch=getchar();
						break;
					case'>':                      //如果符号栈栈顶元素的优先级大于ch,就弹出运算符栈OPTC的栈顶指针,并弹出两个运算数,进行计算,将计算结果压入运算数栈 
						o=OPTC.top();           
						OPTC.pop();
						b=OPTN.top();
						OPTN.pop();
						a=OPTN.top();
						OPTN.pop();
						OPTN.push(Operate(a,o,b));
						//ch=getchar();           //不需要再读入一个,因为刚才读进来的那个还没用,用的这个是从栈里出来的
						break;
					case'=':
						OPTC.pop();             //如果相等,脱括号
						ch=getchar();
						break;
				}
			}
		}
		cout<<"最终运算结果为:";
		cout<<OPTN.top()<<endl;
		cout<<"请问您是否需要继续计算?(1.继续 0.退出):";
		cin>>flag; 
	}
	return 0;
}

本期分享到这里就结束啦,大家如果对小编的代码有疑问或者想要小编做其他的程序,都欢迎来私信小编呀!

相关标签: 小程序代码分享