ACM第二站————STL之stack
栈,作为一种最基础的数据结构(栈还是一种内存的存储形式,就不介绍了),在各种数据结构的题目都会间接或者直接用到。
栈是一种受到限制的线性表,其限制是仅允许在表的一端进行插入和删除运算。这也给予了栈的一个特性————先进后出(FILO)。
利用这一性质,我们可以试着去尝试下做出一个简易的计算器!
下面实战开始:
1.括号匹配
现在,有一行括号序列,请你检查这行括号是否配对。
- 输入
- 第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符
- 输出
- 每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
- 样例输入
- 3
- [(])
- (])
- ([[]()])
- 样例输出
- No
- No
- Yes
- 思路:
- 利用栈的特性,进行匹配。当 是 ( 或者 [ 入栈 。遇到 ) 或 ] 则匹配栈顶元素。
//Asimple #include <iostream> #include <cstdio> #include <stack> using namespace std; int T; stack<char> S; char str[10005]; int main() { cin >> T ; while( T -- ) { bool flag = true ; scanf("%s",str); for(int i=0; str[i]!=0; i++) { if( str[i]=='(' || str[i]=='[' ) S.push(str[i]); else if( str[i] == ')' ) { if( S.empty() || S.top() != '(' ) { flag = false ; break; } else S.pop(); } else { if( S.empty() || S.top() != '[' ) { flag = false ; break ; } else S.pop(); } } if( flag ) cout << "Yes" << endl ; else cout << "No" << endl ; while( !S.empty() ) S.pop();//初始化栈 } return 0; }
接下来就直接写计算器吧!O(∩_∩)O
#include<cstdio> #include<iostream> #include<stack> #include<cctype> #include<cmath> using namespace std; stack<double> Opnd;//操作数栈 stack<char> Optr;//运算符栈 void Init()//栈的初始化 { while(!Opnd.empty()) Opnd.pop(); while(!Optr.empty()) Optr.pop(); Optr.push('=');//先压入一个结束符‘=’ } char Precede(char i,char j) //判断i和j的优先级 { switch(i) { case '+': case '-': if(j=='+'||j=='-'||j==')'||j=='=') return '>'; else return '<'; case '*': case '/': if(j=='(') return '<'; else return '>'; case '(': if(j==')') return '='; else return '<'; case ')': return '>'; case '=': if(j=='=') return '='; else return '<'; } } double Operate(double a,char i,double b)//计算 { switch (i) { case '+': return a+b; case '-': return a-b; case '*': return a*b; case '/': return a/b; } } int judge(char c)//判断---如果c为数字则返回1;若为小数点则返回2;如果c为操作符或者结束符则返回0;; { if(isdigit(c)) return 1; else if(c=='.') return 2; else return 0; } double EvaluateExpression(char *p) { double a,b,temp; int flag; char *st,*end,c,theta; //定义操作符theta Init(); c=*p; while(c!='='||Optr.top()!='=')//即当操作符栈和当前读入的字符都是‘=’时结束循环 { if(isdigit(c))//isdigit(c) 如果c是数字,则返回true; isalpha(c) 如果c是字母,则为true; { temp=0; flag=0; for(;judge(c);c=*(++p)) //当不是数字或小数点时结束循环 { if(judge(c)==1) //说明是数字 { temp=temp*10+c-'0'; if(c!=0) end=p; } else //说明是小数点 { st=p; //记录下小数点的位置 end=p; //记录小数点后最后一个非零数字的位置 flag=1; //标记有小数点 } } if(flag) //调整小数点的位置 temp=temp/pow(10,end-st); Opnd.push(temp); //记录的数字进栈 } else { switch(Precede(Optr.top(),c)) { case '<': //栈顶元素优先权低 Optr.push(c); c=*(++p); break; case '>': //栈顶元素优先权高---退栈并将运算结果入栈 theta=Optr.top(); Optr.pop(); a=Opnd.top(); Opnd.pop(); b=Opnd.top(); Opnd.pop(); Opnd.push(Operate(b,theta,a)); break; case '=': //脱括号并接收下一字符 Optr.pop(); c=*(++p); } } } return Opnd.top(); } int main() { int T; char s[1000]; scanf("%d",&T); while(T--) { scanf("%s",s); printf("%.2lf\n",EvaluateExpression(s)); } return 0; }
低调做人,高调做事。