C++用栈实现计算器四则运算

C++实现四则运算的由来

           

     有些人可能很奇怪,为什么四则运算要自己写代码,直接cout不就行了吗,其实不然,当我们想写一个程序进行四则运算时,程序接收到的四则运算表达式是string字符串类型,不能直接进行运算,所以要我们自己写代码。

实现四则运算的方法

            

       我们平时见到的四则运算表达式被称为‘‘中缀表达式’’中缀表达式的意思就是运算符在操作数的中间,例如1+1   ,1+2+(3+4),这些都是中缀表达式,这些运算表达式符合我们人类的思考逻辑方式,但是愚蠢的计算机用“后缀表达式”进行运算会更加方便,后缀表达式也被称为逆波兰表式。

       

中缀表达式后缀表达式
a+bab+
a*bab*
a+b*cabc*+

                                                                                                                

        网上大部分的教程都是一步到位用中缀表达式直接进行运算,利用栈的先进后出的特性设立一个数字栈,一个运算符栈,不过这种一步到位的方法不太适合新手,不利于新手理解,其实在中缀表达式计算的中间还存在有一步,就是中缀表达式先转换为后缀表达式,我们先对这一步的原理进行讲解,最后再一步到位,学习中缀表达式直接运算。

       

         我们首先来学习如何将中缀表达式化为后缀表达式,这里我们要用到栈的力量,

        化为后缀表达式我们仅仅需要用到一个栈,运算符栈 

        首先我们需要了解各种运算符他们的所对应的优先级

        运算符的优先级排序

                

                1.        (

                2.        +       -

                3.        *       /

                4.        )

                优先级排序从小到大如上所示,下面我们对中缀表达式进行遍历

               例:1+(2-3)*4+4/2

                首先,当我们遇到数字时直接添加到后缀表达式末尾,

                那我们开始了,首先从中缀表达式中拿下来 ‘1’放到后缀表达式末尾

                然后把‘+’拿下来,首先判断运算符栈是否为空栈,若为空栈直接入栈,倘若不是空栈,                  将其与栈顶元素相比较,若比栈顶元素优先级大,

                 直接入栈,若比栈顶元素优先级小,或等于栈顶元素优先级,则将栈顶元素出栈

                 放进后缀表达式中,此处可以判断为空栈,直接入栈 

                

                这里忘了说一点,遇到左括号,不用理会优先级,直接入栈,例子这里就直接入栈 

 

                接下来遇到“2”,送入后缀表达式 ,然后是"-",因为其比栈顶元素"("优先级高,所以直                   接入栈,遇到3,送入后缀表达式,

        然后遇到右括号,当我们遇到右括号时,也是一种特殊情况,右括号不用进栈, 

        而是将运算符栈中的元素从栈顶依次拿出放入后缀表达式中,直到遇到左括号,则将左括号            出栈,操作停止。

        得到后缀表达式:123-

        然后到“*”这个运算符,计算按照优先级入栈,比栈顶的元素“+”高,入栈,数字送入后缀表达式,“-”比"*"优先级小,则将栈顶的*出栈送入后缀表达式中

后续,就由各位网友自己来完成啦

                最后我们得到后缀表达式:1 2 3 - 4* + 4 2 / +

                后缀表达式就符合计算机思考的方式,方便我们加下来用程序进行运算。下面来介绍一

                下后缀表达式的计算方法。

后缀表达式的计算方法

                后缀表达式的计算就相当简单了。准备一个数字栈。从左到右扫描后缀表达式,如果是数字,放入数字栈。如果是符号,从数字栈中弹出两个数字,第一个取出的数字为右运算数,第二个为左运算数,进行运算。然后将结果放进数字栈中。如此反复,直到读完整个表达式后,留在数字栈中的那个数字就是最终结果。

直接通过中缀表达式计算

                接下来,就是直接通过中缀表达式进行计算,从前面我们了解到在中缀表达式转化为后缀表达式时用到了 运算符栈,在计算后缀表达式时用到了数字栈,那么直接计算的话,我们就可以通过同时建立两个栈,一个数字栈,一个运算符栈来完成。

下面来展示下相应的C++代码

​
#include<iostream>
#include<string>
#include<stack>
#include <ctype.h>
#include <stdlib.h>
using namespace std;
int youxianji(char);
void calcutor(string);
int main()
{
	
	string str="1+(2-3)*4+4/2";    //要计算的四则运算表达式
	calcutor(str);    
 } 

int youxianji(char op)    //优先级判断函数,通过接受字符串内的每个字符进行判断
{
	if(op=='(')
	return 1;
	else if(op=='+'||op=='-')
	return 2;
	else if(op=='*'||op=='/')
	return 3;
	//else
	//return 4;
}
void calcutor(string str)    //计算函数接受字符串
{
	
	stack<double>number;    //创建数字栈
	stack<char>operator1;   //创建字符栈
	int i=0,j;
	int length=str.size();  //获取字符串长度
	string number2;         //用来获取字符串中的数字
	while(i<length)         //首先进行长度判断   
	{
		if(str[i]>='0'&&str[i]<='9')    //判断是否为数字
		{
				
		
			j=i;
			while(j<length&&str[j]>='0'&&str[j]<='9')    //获取后一个运算符之前的所有数字
			{
				j++;
			}
			number2=str.substr(i,j-i);            //利用了字符串截取函数
			number.push(atoi(number2.c_str()));   //这里用到了c语言的atoi函数
			i=j;
		}
		/*else if(str[i]=='+'||str[i]=='-'||str[i]=='*'str[i]=='/')
		{
			if()
		}*/
		 if((operator1.empty()||str[i]=='('))          //当运算符栈为空,或字符为左括号时直接进栈
		{
		
			operator1.push(str[i]);
		
		 } 
		 else if(str[i]==')')                    //当字符为右括号时的操作
		 {
		 	while(operator1.top()!='(')        //直到碰到左括号
		 	{
		 		double b,c,d;
		 	b=number.top();                    //拿出两个操作数,第一个为右操作数,第二个为左操作数,并弹栈
		 	number.pop();
		 	c=number.top();
		 	number.pop();
		 	if(operator1.top()=='+')
		 	{
		 		d=c+b;
			 }
			else if(operator1.top()=='-')
		 	{
		 		d=c-b;
			 }
			else if(operator1.top()=='*')
		 	{
		 		d=c*b;
			 }
			else if(operator1.top()=='/')
		 	{
		 		d=c/b;
			 }
			 number.push(d);
			 operator1.pop();    //将操作符弹出
			 }
			 operator1.pop();    //将左括号弹出
		 }
		 else if((str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')&&(youxianji(operator1.top())<youxianji(str[i])))       //当运算符栈不为空时,先判断字符是否为运算符(其实这一步可以在判断优先级的函数里完成),再判断优先级
		 {
		 	operator1.push(str[i]);
		 }
		 else if((str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')&&(youxianji(operator1.top())>=youxianji(str[i])))
		 {
		 	 
		 	double b,c,d;
		 	b=number.top();
		 	number.pop();
		 	c=number.top();
		 	number.pop();
		 	if(operator1.top()=='+')
		 	{
		 		d=c+b;
			 }
			else if(operator1.top()=='-')
		 	{
		 		d=c-b;
			 }
			else if(operator1.top()=='*')
		 	{
		 		d=c*b;
			 }
			else if(operator1.top()=='/')
		 	{
		 		d=c/b;
			 }

			 number.push(d);
			 operator1.pop();
			 operator1.push(str[i]);

		 }
		 i++;
	}
	while(!operator1.empty())    //遍历完成后,倘若运算符栈不是空栈,则继续将运算符栈中的运算符一个个弹出,并到数字栈中弹栈进行运算
	{

			double b,c,d;
		 	b=number.top();
		 	number.pop();
		 	c=number.top();
		 	number.pop();
		 	if(operator1.top()=='+')
		 	{
		 		d=c+b;
			 }
			else if(operator1.top()=='-')
		 	{
		 		d=c-b;
			 }
			else if(operator1.top()=='*')
		 	{
		 		d=c*b;
			 }
			else if(operator1.top()=='/')
		 	{
		 		d=c/b;
		 	
			 }
			  number.push(d);
			  
			 operator1.pop();
	}
double e,f;
	e=number.top();
	f=number.size();
	cout<<number.top()<<endl;
	cout<<f;
	}
	

​

总结

在截取数字时用到了C语言的atoi函数,所以要使用相应的头文件stdlib.h,并且c++在使用这个函数时给这个函数传参需要用到c_str函数来将c++的string类型转换为字符串指针类型,才能让c语言的函数接受。ctype.h头文件可以不用用到,因为一开始想用isdigit()函数,但是后面发现不可行。

如果大家想让这个程序可以接受用户输入来进行运算,可以自行添加cin等操作,加个while死循环等操作。

  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值