ACM第二站————STL之stack
栈,作为一种最基础的数据结构(栈还是一种内存的存储形式,就不介绍了),在各种数据结构的题目都会间接或者直接用到。
栈是一种受到限制的线性表,其限制是仅允许在表的一端进行插入和删除运算。这也给予了栈的一个特性————先进后出(FILO)。
利用这一性质,我们可以试着去尝试下做出一个简易的计算器!
下面实战开始:
1.括号匹配
现在,有一行括号序列,请你检查这行括号是否配对。
- 输入
- 第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符
- 输出
- 每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
- 样例输入
- 3
- [(])
- (])
- ([[]()])
- 样例输出
- No
- No
- Yes
- 思路:
- 利用栈的特性,进行匹配。当 是 ( 或者 [ 入栈 。遇到 ) 或 ] 则匹配栈顶元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | //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; }
低调做人,高调做事。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理