zoukankan      html  css  js  c++  java
  • ybt 1356 计算(calc)

    题目链接

    看到题目,毫无疑问,这是道大模拟+栈。

    对于中缀表达式,不做任何处理来计算出结果是十分麻烦的,所以我利用了刚刚学的栈来转换成后缀表达式来做。

    将中缀表达式转换为后缀表达式,遵循如下法则:

    1. 遇到数字,直接将数字输出;

    2. 遇到运算符,比较其与栈顶的优先级,如果栈顶运算符的优先级比当前运算符高,则一直输出并弹出栈顶元素直到栈顶的优先级比当前运算符低为止(或者遇到正括号了),将运算符压入。

    3. 遇到正括号,直接压入,遇到反括号,持续弹出运算符直到遇到最近的正括号为止,然后弹出正括号,但正反括号均不输出。(注意:遇到N/(A*B+C)这种情况时,弹出的乘号是直接输出,而非转换后存在括号里)

    最后注意把运算符弹出完。

    代码如下
    #include <bits/stdc++.h>
    using namespace std;
    string str;
    char sc[100005];//运算符栈
    map<char,int>a;//运算符优先级映射
    struct node{
    	int type;//type为1表示运算符,type为0表示数字
    	int num;
    }st[200005];//存储后缀表达式
    int top=0,toc=0;
    int main() {
    	a['+']=1;//定义优先级
    	a['-']=1;
    	a['*']=2;
    	a['/']=2;
    	a['^']=3;
    	cin>>str;
    	for(int i=0;i<str.size();i++){
    		if(str[i]<='9'&&str[i]>='0'){//转换数字
    			int sum=0;
    			while(str[i]<='9'&&str[i]>='0'){
    				sum=sum*10+str[i]-'0';
    				i++;
    			}
    			i--;
    			st[++top].type=0;
    			st[top].num=sum;//直接输出
    		}else{
    			switch(str[i]){
    				case '(':{//正括号
    					sc[++toc]=str[i];
    					break;
    				}
    				case ')':{//反括号
    					while(sc[toc]!='('){
    						st[++top].type=1;
    						st[top].num=(int)sc[toc];
    						toc--;
    					}
    					toc--;
    					break;
    				}
    				default:{//运算符
    					while(a[sc[toc]]>=a[str[i]]&&sc[toc]!='('){
    						st[++top].type=1;
    						st[top].num=(int)sc[toc];
    						toc--;
    					}
    					sc[++toc]=str[i];
    					break;
    				}
    			}
    		}
    		/*
    		for(int j=1;j<=toc;j++){
    			cout<<sc[j];
    		}
    		cout<<endl;
    		for(int j=1;j<=top;j++){
    			if(st[j].type==0){
    				cout<<st[j].num;
    			}else{
    				cout<<(char)st[j].num;
    			}
    		}
    		cout<<endl;
    		getchar();
    		*/
    	}
    	while(toc){//记得弹出
    		st[++top].type=1;
    		st[top].num=(int)sc[toc];
    		toc--;
    	}
    	/*
    	for(int i=1;i<=top;i++){
    		if(st[i].type==0){
    			cout<<st[i].num<<' ';
    		}else{
    			cout<<(char)st[i].num<<' ';
    		}
    	}
    	cout<<endl;
    	*/
    	return 0;
    }
    

    ​ 然后是将后缀表达式计算出来,对于计算机而言,后缀表达式没有优先级之类麻烦的东西,可以大胆地去算。运算法则如下:

    1. 如果遇到数字,直接压入栈中。
    2. 如果遇到运算符,将栈顶两个元素弹出进行计算,再将计算的结果压入栈中。(注意:减法、除法、乘方是有先后顺序的,切记不可搞错)。
    代码如下
    #include <bits/stdc++.h>
    using namespace std;
    string str;
    struct node{
    	int type;
    	int num;
    }st[200005];
    int num[100005];
    int top=0,ton=0;
    int main() {
    	for(int i=1;i<=top;i++){
    		if(st[i].type==0){
    			num[++ton]=st[i].num;//数字入栈
    		}else{
    			int x,y,z;
    			switch((char)st[i].num){//字符计算
    				case '+':{
    					x=num[ton--];
    					y=num[ton];
    					z=x+y;
    					num[ton]=z;
    					break;
    				}
    				case '-':{
    					x=num[ton--];
    					y=num[ton];
    					z=y-x;//注意顺序
    					num[ton]=z;
    					break;
    				}
    				case '*':{
    					x=num[ton--];
    					y=num[ton];
    					z=x*y;
    					num[ton]=z;
    					break;
    				}
    				case '/':{
    					x=num[ton--];
    					y=num[ton];
    					z=y/x;//注意顺序
    					num[ton]=z;
    					break;
    				}
    				case '^':{
    					x=num[ton--];
    					y=num[ton];
    					z=pow(y,x);//注意顺序
    					num[ton]=z;
    					break;
    				}
    			}
    		}
    		/*
    		for(int i=1;i<=ton;i++){
    			cout<<num[i]<<' ';
    		}
    		cout<<endl;
    		getchar();
    		*/
    	}
    	cout<<num[1];//最后的结果即为数字栈顶
    	return 0;
    }
    

    ​ 最后总的代码就是这样了:

    100分AC代码:
    #include <bits/stdc++.h>
    using namespace std;
    string str;
    char sc[100005];
    map<char,int>a;
    struct node{
    	int type;
    	int num;
    }st[200005];
    int num[100005];
    int top=0,toc=0,ton=0;
    int main() {
    	a['+']=1;
    	a['-']=1;
    	a['*']=2;
    	a['/']=2;
    	a['^']=3;
    	cin>>str;
    	for(int i=0;i<str.size();i++){
    		if(str[i]<='9'&&str[i]>='0'){
    			int sum=0;
    			while(str[i]<='9'&&str[i]>='0'){
    				sum=sum*10+str[i]-'0';
    				i++;
    			}
    			i--;
    			st[++top].type=0;
    			st[top].num=sum;
    		}else{
    			switch(str[i]){
    				case '(':{
    					sc[++toc]=str[i];
    					break;
    				}
    				case ')':{
    					while(sc[toc]!='('){
    						st[++top].type=1;
    						st[top].num=(int)sc[toc];
    						toc--;
    					}
    					toc--;
    					break;
    				}
    				default:{
    					while(a[sc[toc]]>=a[str[i]]&&sc[toc]!='('){
    						st[++top].type=1;
    						st[top].num=(int)sc[toc];
    						toc--;
    					}
    					sc[++toc]=str[i];
    					break;
    				}
    			}
    		}
    		/*
    		for(int j=1;j<=toc;j++){
    			cout<<sc[j];
    		}
    		cout<<endl;
    		for(int j=1;j<=top;j++){
    			if(st[j].type==0){
    				cout<<st[j].num;
    			}else{
    				cout<<(char)st[j].num;
    			}
    		}
    		cout<<endl;
    		getchar();
    		*/
    	}
    	while(toc){
    		st[++top].type=1;
    		st[top].num=(int)sc[toc];
    		toc--;
    	}
    	/*
    	for(int i=1;i<=top;i++){
    		if(st[i].type==0){
    			cout<<st[i].num<<' ';
    		}else{
    			cout<<(char)st[i].num<<' ';
    		}
    	}
    	cout<<endl;
    	*/
    	for(int i=1;i<=top;i++){
    		if(st[i].type==0){
    			num[++ton]=st[i].num;
    		}else{
    			int x,y,z;
    			switch((char)st[i].num){
    				case '+':{
    					x=num[ton--];
    					y=num[ton];
    					z=x+y;
    					num[ton]=z;
    					break;
    				}
    				case '-':{
    					x=num[ton--];
    					y=num[ton];
    					z=y-x;//注意 
    					num[ton]=z;
    					break;
    				}
    				case '*':{
    					x=num[ton--];
    					y=num[ton];
    					z=x*y;
    					num[ton]=z;
    					break;
    				}
    				case '/':{
    					x=num[ton--];
    					y=num[ton];
    					z=y/x;//注意 
    					num[ton]=z;
    					break;
    				}
    				case '^':{
    					x=num[ton--];
    					y=num[ton];
    					z=pow(y,x);//注意 
    					num[ton]=z;
    					break;
    				}
    			}
    		}
    		/*
    		for(int i=1;i<=ton;i++){
    			cout<<num[i]<<' ';
    		}
    		cout<<endl;
    		getchar();
    		*/
    	}
    	cout<<num[1];
    	return 0;
    }
    

    大功告成!

  • 相关阅读:
    mybatis 错误 Invalid bound statement (not found)
    Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
    bug 记录 Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans
    解决:The Tomcat connector configured to listen on port 8182 failed to start. The port may already be in use or the connector may be misconfigured.
    jquery validate 验证插件 解决多个相同的Name 只验证第一个的方案
    phpStorm+xdebug调试(php7.3)
    小程序视频多个视频播放与暂停
    CSS实现单行、多行文本溢出显示省略号(…)
    Packet for query is too large (4,544,730 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.
    idea自动在文件头中添加作者和创建时间
  • 原文地址:https://www.cnblogs.com/returnG/p/13088965.html
Copyright © 2011-2022 走看看