王道复试C语言第四章线性数据结构(下:栈)——代码笔记分享

文章展示了C++中栈数据结构的几个应用,包括零复杂度转置序列、括号匹配问题的解决以及一个简单的计算器实现,通过标准库函数<stack>处理括号和算术表达式计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用C++的标准库函数

#include <stack>

基础知识

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stack>
using namespace std;

int main() {
	stack<int> myStack;
	for (int i = 0; i < 10; i++) {
		myStack.push(i);//压栈
	}
	printf("size of myStack = %d\n", myStack.size());//求栈的大小
	while (!myStack.empty()) {//判断栈不为空
		printf("cur top = %d\n", myStack.top());//获取栈顶元素
		myStack.pop();//出栈
	}
	printf("myStack is empty!\n");
}

5.4Zero-complexity Transposition

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stack>
using namespace std;

/*
描述:
You are given a sequence of integer numbers. Zero-complexity transposition of the sequence is the reverse of this sequence.
Your task is to write a program that prints zero-complexity transposition of the given sequence.
输入描述:
For each case, the first line of the input file contains one integer n-length of the sequence (0 < n ≤ 10 000). 
The second line contains n integers numbers-a1, a2, …, an (-1 000 000 000 000 000 ≤ ai ≤ 1 000 000 000 000 000).
输出描述:
For each case, on the first line of the output file print the sequence in the reverse order.
*/

int main() {
	stack<long long> trans;
	int n;
	long long num;//范围:-2^63~2^63-1
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%lld", &num);//%lld 读取longlong类型的十进制数
		trans.push(num);
	}
	while (!trans.empty()) {
		printf("%lld ", trans.top());
		trans.pop();
	}
}

5.5扩号匹配问题

OJ
(加入小组才能提交?)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stack>
#include <string>
using namespace std;
/*
描述:
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;
规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。
写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。
不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注.
输入:
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100
注意:cin.getline(str,100)最多只能输入99个字符!
输出:
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配。
*/

int main() {
	char buf[200];
	while (fgets(buf, 200, stdin) != NULL) {
		//用fgets配合while实现不确定数量的多行读取
		string str = buf;
		str.pop_back();//去掉fgets得到的额外的换行

		stack<int> indexStack;//存储了左圆括号的下标
		string res;//保存输出的结果
		for (int 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());
	}
}

5.6简单计算器counter

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stack>
#include <string>
#include <map>
using namespace std;

/*
描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入描述:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。
    当一行中只有0时输入结束,相应的结果不要输出。
输出描述:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
*/

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();
        for (int i = 0; i < expr.size(); i++) {
            if (expr[i] == '0') {
                break;
            }
        }
        expr.push_back('$');//补充一个虚拟的终止符

        string num;//用来搜集单独的0-9以组成一个数字1 2 3 4->1234
        stack<double> numstack;//数字栈
        stack<char> operstack;//符号栈
        for (int i = 0; i < expr.size(); i++) {
            if (expr[i] >= '0' && expr[i] <= '9') {//数字,用num链接
                num.push_back(expr[i]);
            }
            else if (expr[i] == ' ') {//空格
                if (num != "") {//若之前是数字,证明数字结束
                    numstack.push(stod(num));//stod-->string to double
                    num = "";//初始化
                }
            }
            else {//字符
                if (expr[i] == '$') {//结束符
                    if (num != "") {//若之前是数字,证明数字结束
                        numstack.push(stod(num));//stod-->string to double
                        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;
                    default:
                        break;
                    }
                }
                //所有比expr[i]优先级更高的运算符都计算过了
                operstack.push(expr[i]);
            }
        }
        printf("%.2f\n", numstack.top());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值