计算器功能实现(栈)

计算器功能实现(栈)

input

15*5+(5+1)/6-7

output

69

解题思路

  1. 因为在实际计算中要考虑优先级的问题,所以我们需要建立一个函数,在这里我将它命名为get(char x), x是我们输入的式子,我将”(”的优先级设为最低为‘0‘,其次是’+‘和’-‘为1,’*‘,’/‘的优先级为2,^的优先级最高为3。我们还需要建立一个用于计算临时部分结果的函数,这里我将其命名为ls(int a,int b, int c)c为我们从中取出的运算符,a,b,是我们从栈中取出的两个相邻的数值,因为先进后出的原则,所以我们要把先取出来的放在后面进行计算,不然会导致结果的错误。
  2. 在输入式子之后,我们我们先建立两个栈,分别存放数值与符号,再利用size计算我们式子的长度,用于循环。为了能够读取多位的数值,我们利用k的不断乘10再加上个位的不断循环来进行计算。当计算完毕后将其压入数字栈中。
  3. 当遇到字符时我们需要进行判断,当遇到“(”时,直接压入符号栈中,到遇到不是括号的字符,我们需要将其与栈顶的字符进行优先级对比,若栈顶为空或者栈顶优先级小于我们读取符号的优先级则直接压入栈中,栈顶优先级大于我们当前遍历到的字符的优先级,则先将栈顶的符号取出,从数字栈中取出两个数值进行计算,取出后记住需要将栈顶pop,计算完之后需要将计算完的数值重新压回栈中。一直循环,直到栈顶的字符优先级小于我们当前字符的优先级,再将当前字符压入栈中。再进行下一步的遍历。
  4. 当遇到“)“时,需要停止对式子之后进行遍历,需要不断的从栈中取出已经按照优先级排好了了的字符进行运算,直到遍历到遇到”(”停止。然后继续遍历,当遍历完之后,需要对栈中剩下的字符数字进行计算,直到字符栈为空。最后取出数字栈的栈顶,结束。

示例

15∗5+(5+1)/6-7

  1. 先遍历到1是个数字k=0∗10+1=1
  2. 第二个是5还是个数字k=1∗10+5=15
  3. 第三个遍历到∗,不是数字,15压入数字栈,因为字符栈为空,所以∗直接压入栈中
  4. 第四个遍历到5是数字,k=0∗10+5=5
  5. 第五个遍历到+不是数字,5压入数字栈,∗的优先级高于+,所以取出∗,5,15,进行计算m=15∗5=75(记住15要在前面,先进后出,后进先出,乘法虽然没有什么大碍但是若遇到减法则会出现很大差别)将5,15弹出75压入数字栈中,符号栈弹出∗,则符号栈空,则压入+,继续遍历
  6. 第六个遍历到(,直接入栈
  7. 第七个5是数字,k=0∗10+5=5
  8. 第八个是+不是数字,将5压入数字栈,因为(的优先级最低所以+的优先级大于(的优先级,所以将+直接压入栈顶
  9. 第九个是1,是数字,k=0∗10+1=1
  10. 第10个是),不是数字,将1压入数字栈,因为碰到了),则需要停止对后续的遍历,直到弹出(为止,则取出数字栈中的1,5,符号栈中的栈顶+,进行计算m=5+1=6,将1,5弹出然后弹出+,后续栈顶为(,弹出(,此时栈中还剩下+,数字栈顶压入6之后从栈底开始还有75,6
  11. 第11个是/,/的优先级大于+,所以/直接入栈
  12. 第12个是6,是数字,k=0∗10+6=6
  13. 第13个是-,不是数字,将6,压入数字栈-的优先级小于/,于是取出/,6,6,进行计算m=6/6=1,将6,6弹出1压入数字栈,/推出栈,目前符号栈还剩+,+的优先级=-,则取出+,1,75进行运算,m=75+1=76,符号栈弹出+,压入-,数字栈弹出1,75压入76
  14. 最后遍历到7,压入数字栈,遍历结束后,将栈中剩余已经排号的符号运算完毕取出-,7,75,
    m=76-7=69;弹出-,弹出7,76,压入69,此时符号栈为空,数字栈的栈顶为69,也是数字栈中唯一一个数字,最终结果为69;

代码展示及注释

#include<bits/stdc++.h>
using namespace std;
stack<char>fh;//建立字符栈 
stack<int>sz;//建立数字栈 
string t;
int sum=0,p1,p2,m;
int get(char x)//判断优先级 
{
    
    
	if(x=='(') return 0;
	if(x=='+'||x=='-') return 1;
	if(x=='*'||x=='/') return 2;
	if(x=='^') return 3;
 } 
int ls(int a,int b,char c)//利用从栈中取出的数值与符号来计算 
{
    
    
	if(c=='+') return b+a;//由于栈先进后出,所以要将先取出来的数值放在后面,否则会造成结果的错误 
	if(c=='-') return b-a;
	if(c=='*') return b*a;
	if(c=='/') return b/a;
	if(c=='^') return pow(b,a);
}
int main()//主函数 
{
    
    
	cin>>t;
	int i;
	for(i=0;i<t.size();)//遍历字符串t.size();是长度 
	{
    
    	int k=0;
		if(t[i]>='0'&&t[i]<='9')//为了取出多位数的数值 
		{
    
    
			while(t[i]>='0'&&t[i]<='9')//直到遍历到下一个不是数字为止 
			{
    
    
			k=k*10+t[i]-'0';
			i++;
			}
			sz.push(k);//将取出来的数值压入栈中 
		}
		else{
    
    
			if(t[i]=='(') fh.push(t[i]);//当遇到'('时,直接压入栈 
			else if(t[i]!=')')
			{
    
    
				if(fh.empty()||get(fh.top())<get(t[i])) fh.push(t[i]);//当栈顶为空或者栈顶优先级小于我们读取符号的优先级则直接压入栈中
				else
				{
    
    
					while(!fh.empty()&&get(fh.top())>=get(t[i]))//当栈顶的优先级大于我们当前遍历到的符号,则将栈中的符号进行运算,直到栈顶的符号优先级小于当前符号为止 
					{
    
    
					p1=sz.top();sz.pop();
					p2=sz.top();sz.pop();
					m=ls(p1,p2,fh.top());
					fh.pop(); 
					sz.push(m);
					}
					fh.push(t[i]);
				}
			}
			else
			{
    
    
				while(fh.top()!='(')//当遇到右括号时,会停止对式子之后进行遍历,需要不断的从栈中取出已经按照优先级排好了了的字符进行运算,直到遍历到遇到"("停止 
					{
    
    
					p1=sz.top();sz.pop();
					p2=sz.top();sz.pop();
					m=ls(p1,p2,fh.top());
					fh.pop(); 
					sz.push(m);
					}
					fh.pop();
			}
			i++;
		}
	}
	while(!fh.empty())//对剩下栈中的字符进行计算 
	{
    
    
		p1=sz.top();sz.pop();
		p2=sz.top();sz.pop();
		m=ls(p1,p2,fh.top());
		fh.pop(); 
		sz.push(m);
	}
	sum=sz.top();//数字栈顶元素即为最终值 
	cout<<sum<<endl;
	return 0;
}

结尾

希望对大家有帮助!!!
有问题可在下面留言,谢谢…

猜你喜欢

转载自blog.csdn.net/weixin_53777651/article/details/122191219
今日推荐