考研复试机试 | C++ | 王道机试课程笔记

文章介绍了如何使用C++标准库中的栈数据结构解决三个算法问题:零复杂度序列反转,括号匹配验证和表达式计算。通过读取输入,压栈,判断和弹栈操作,实现了对整数序列的反转,检查括号的合法性和计算数学表达式的功能。

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

标准库里提供了栈

stack<typename> myStack
.size() 栈的大小
.push() 压栈
.top() 获取栈顶元素
.pop() 弹栈
.empty()判断栈是否为空

整数的数据类型
在这里插入图片描述

Zero-complexity (上交复试题)

题目:

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.

示例1
输入
5
-3 4 6 -8 9
输出
9 -8 6 4 -3

代码:

#include <stack>
#include <cstdio>

using namespace std;

int main(){
	// 题目中介绍的数据范围大概是10的15次方,int不可以用 
	stack <long long> myStack;
	int n;
	long long num;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%lld",&num); //%lld 读取long long类型的六进制数
		myStack.push(num);
	}
	while(!myStack.empty()){
		printf("%lld ",myStack.top());
		myStack.pop(); 
	}
	printf("\n");
}

读取字符串的操作
在这里插入图片描述
在这里插入图片描述

括号匹配问题

题目:

在这里插入图片描述

代码:

#include <stack>
#include <cstdio>
#include <string> 

using namespace std;

int main(){
	char buf[200];
	while(fgets(buf,200,stdin)!=NULL){
		// fgets配合while实现不确定数量的多行读取
		string str = buf; //转化为C++风格的字符串 
		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原左括号的值改为空格 
					res.push_back(' ');
					res[indexStack.top()] = ' ';
					indexStack.pop(); 
				}
			}
			// 如果是字母 
			else{
				res.push_back(' ');
			} 
		} 
		// 输出 
		printf("%s\n%s\n",str.c_str(),res.c_str()); 
		
	}
}

表达式解析问题 (浙大机试题)

题目:

读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

输入描述:
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

输出描述:
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

示例1
输入:
1 + 2
4 + 2 * 5 - 7 / 11
0

输出:
3.00
13.36

代码:

#include <stack>
#include <cstdio>
#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; 
		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)); // stod --> string to double
					num = ""; // num置空 
				}
			}
			// 扫描到运算符 
			else{
				if(expr[i] == '$'){
					if(num!=""){
					numstack.push(stod(num)); // stod --> string to double
					num = ""; // 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;
					} 
				}
				//所有比expr[i]优先级更高的运算符都计算过了 
				// 接下来吧这个高优先级的运算符入栈
				operstack.push(expr[i]); 
			}	 
		} 
		
		// 所有的计算都结束了,此时数字栈中存放的是最终结果 
		printf("%.2f\n",numstack.top()); 
	}
}
### 计算机考研复试中的常见算法题型 在计算机考研复试过程中,考生通常会遇到多种类型的算法题目。这些题目旨在评估候选人的编程技能、逻辑思考能力和解决复杂问题的能力。 #### 一、数据结构操作类题目 这类题目主要考察候选人对各种常用数据结构的理解及其应用能力。常见的有链表反转、二叉树遍历(前序、中序、后序)、堆栈与队列的操作等[^3]。 ```cpp // C++实现单向链表节点定义及简单功能函数 struct ListNode { int val; struct ListNode *next; ListNode(int x):val(x), next(NULL){} }; ListNode* reverseList(ListNode* head){ ListNode *prev = NULL, *curr = head; while (curr != NULL) { ListNode* tempNext = curr->next; // Store the rest of list. curr->next = prev; // Reverse link direction. prev = curr; // Move forward one node. curr = tempNext; // Continue with remaining nodes. } return prev; // New head is at 'prev'. } ``` #### 二、动态规划(DP)问题 动态规划是一种通过把原问题分解成更简单的子问题来求解的方法。它适用于具有重叠子问题性质的问题。例如最长公共子序列(LCS),背包问题都是经典的DP案例。 ```python def lcs_length(X , Y): m = len(X) n = len(Y) # 创建一个二维数组用于存储中间结果 L = [[None]*(n+1) for i in range(m+1)] """构建L[i][j],其中i=0..m and j=0..n""" for i in range(m+1): for j in range(n+1): if i == 0 or j == 0 : L[i][j] = 0 elif X[i-1]: L[i][j] = L[i-1][j-1]+1 else: L[i][j] = max(L[i-1][j] , L[i][j-1]) # 返回X和Y的最大长度 return L[m][n] ``` #### 三、图论相关问题 涉及最短路径(Floyd-Warshall/Dijkstra/Bellman-Ford)、最小生成树(Prim/Kruskal)以及拓扑排序等问题。这些问题不仅测了学生对于特定算法的记忆程度,更重要的是考验其能否灵活运用所学知识解决问题。 ```java import java.util.*; public class DijkstraAlgorithm { private static final Graph.Edge[] GRAPH = { new Graph.Edge("a", "b", 7), new Graph.Edge("a", "c", 9), ... }; public static void main(String args[]) throws Exception{ Graph g = new Graph(GRAPH); System.out.println(g.dijkstra("a")); } } class Graph { Map<String, List<Edge>> adjacencies = new HashMap<>(); ... public String dijkstra(String startNodeName) { ... } static class Edge { String v1; String v2; Integer weight; Edge(String aV1, String aV2, Integer aWeight) {...} } } ``` #### 推荐练习资源 为了更好地准备上述提到的各种类型算法题目,《王道机指南》是一个不错的选择,因为这本书籍提供了大量贴近实际考场景的例子,并且难度适中适合初学者入门;而对于那些希望进一步提升自己水平的人来说,则可以尝《算法笔记》,该书涵盖了更多高级主题并注重培养读者处理边界情况的能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭旭老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值