C/C++栈

文章介绍了如何使用C++标准库中的栈数据结构解决两个问题:1)将整数序列反转;2)检查括号匹配并标记未匹配的括号;3)解析数学表达式。在括号匹配中,利用栈来跟踪左括号的位置,而在表达式解析中,栈用于存储运算符和操作数,根据运算符的优先级进行计算。
摘要由CSDN通过智能技术生成

一、栈的基本操作

stack<typename>myStack//定义
.size()//大小
.push()//加入元素到栈中 压栈
.top()//得到栈顶元素
.pop()//弹栈
.empty()//判断栈是否为空

题目

1、零复杂度转换
描述:你被给了一系列整型数,把这个序列反转一下
输入:首先输入一个n,这个n表示这个数组的长度;第二行包含n个元素
整数的数据类型

  • int 4bytes
  • unsigned int 4bytes
  • long long 8bytes
  • unsigned long long 8bytes

代码

#include<stack>
#include<cstdio>
using namespace std;
int main() {
	stack<long long>myStack;
	int n;
	long long num;
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf_s("%lld", &num);//%lld读取long long类型的十进制数
		myStack.push(num);
	}
	while (!myStack.empty()) {
		printf("%lld ", myStack.top());
		myStack.pop();
	}
}

2.括号匹配问题
描述:
再某个字符串(长度不超过100)中有左括号,右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与它右边且距离最近的右括号匹配,再写一个程序,找到无法匹配的左括号和右括号,输出原来的字符串,并在下一行标出不能匹配的括号,不能匹配的左括号用“$"标注,不能匹配的右括号用“?”标注
输入:
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母;字符串长度不超过100
**输出:**对每组输出数据,输出两行,每一行包含原始输入字符,第二行由 '$' '?'表示与之对于的左括号和右括号不能匹配
样例

输入:
)(rttyy())sss)(
输出:
?            ?$

解题思路
采用一个栈,栈中还要记录左括号的位置信息,左括号压栈,右括号弹栈

  • 不匹配的左括号:假定非法,当对应的右括号找不到时就非法
  • 不匹配的右括号:栈空试图弹栈
    读取字符串的操作
    读取单词 char buf[100];scanf(“%s”,buf);
    读取一行 char buf[1000](比题目大一些)fgets(buf,1000,stdin)【额外读一个换行】——>解决方法:string str=buf;str.pop_back();

代码

#include<cstdio>
#include<stack>
#include<string>
using namespace std;
int main() {
	char buf[200];
	while (fgets(buf, 200, stdin) != NULL) {
		//fgets配合while实现不确定数量的多行读取
		string str = buf;
		str.pop_back();//str去掉额外的换行

		stack<unsigned>indexStack;//存储了左圆括号的下标
		string res;//保存输出的结果
		for (unsigned i = 0; i < str.size(); ++i) {
			if (str[i] == '(') {
				indexStack.push(i);//把下标压栈
				//暂且认为这个左圆括号是非法的
				res.push_back('$');
			}
			else if (str[i] == ')') {
				if (indexStack.empty()) {
					res.push_back('?');
				}
				else {
					res.push_back(' ');
					res[indexStack.top()] = ' ';
					indexStack.pop();
				}
			}
			else {
				res.push_back(' ');
			}
		}
		printf("%s\n%s\n", str.c_str(), res.c_str());
	}
}

3、表达式解析的问题

  • 从左往右遍历表达式遇到3类运算符:
    */
    ±
    $(虚拟的终止符号)

  • 后一个运算符的优先级比前面的低/相等,前面的运算符可以运算了

  • 数据结构设计
    stack oper 操作数
    stack num 中间数据

  • 从左往右遍历表达式
    数字 num压栈
    运算符 a高 oper压栈;b先oper弹出一个再num弹出2个,运算

代码

#include<cstdio>
#include<stack>
#include<string>
#include<map>
using namespace std;
int main() {
	char buf[300];
	map<char, int>priority = {
		{'$',0},
		{'+',1},{'-',1},
		{'*',2},{'/',2}
	};
	while (fgets(buf, 300, stdin) != NULL) {
		string expr = buf;
		expr.pop_back();

		if (expr == "0") {
			break;
		}
		expr.push_back('$');
		string num;//收集单独的0-9以组成一个数字 1 2 3 4-->1234
		stack<double>numstack;
		stack<char>operstack;
		for (unsigned i = 0; i < expr.size(); ++i) {
			if (expr[i] >= '0' && expr[i] <= '9') {
				num.push_back(expr[i]);
			}
			else if (expr[i] == ' ') {
				if (num!="") {
					numstack.push(stod(num));//string to double
					num = "";
				}
			}
			else {
				// + - * / $
				if (expr[i] == '$') {
					if (num != "") {
						numstack.push(stod(num));
					}
				}
				while (!operstack.empty() && priority[operstack.top()] >= priority[expr[i]]) {
					//后来的运算符的优先级不高于栈顶的优先级
					char oper = operstack.top();
					operstack.pop();
					double rhs = numstack.top();
					numstack.pop();
					double lhs = numstack.top();
					numstack.pop();
					switch (oper) {
					case '+':
						numstack.push(lhs + rhs);
						break;
					case '-':
						numstack.push(lhs - rhs);
						break;
					case '*':
						numstack.push(lhs * rhs);
						break;
					case '/':
						numstack.push(lhs / rhs);
						break;

					}
				}
				operstack.push(expr[i]);
			}
		}
		printf("%.2lf\n", numstack.top());
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值