C++编程题/左右最值最大差/数据库连接池/mkdir/顺时针打印矩阵

这篇博客涵盖了多个计算机科学领域的知识点,包括C++编程题,如寻找左右最值的最大差;讲解了TCP网络通信的三次握手,Linux网络监控工具tcpdump的使用;讨论了数据库连接池在Web系统中的作用,通过实例分析了最大连接数需求;还介绍了Linux系统中mkdir命令的递归创建子目录功能,并提供了解题思路。最后,提出了一种顺时针打印矩阵的算法问题。

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

问答题

题1:Linux tcpdump监听网卡 eth0,对方主机IP为10.1.1.180,tcp端口为 80 的数据,相应命令为?

提示: tcpdump -i eth0 -nn 'tcp and port 80 and host 10.1.1.180'

其中 i 表示监听指定的端口,-nn表示:直接以 IP 及 port number 显示,而非主机名和服务器名称

题2:tcp 三次握手的过程,accept 发生在三次握手哪个阶段?

A: 第一次握手
B: 第二次握手
C: 第三次握手
D: 三次握手后

在这里插入图片描述

题3:随着IP 网络的发展,为了节省可分配的注册IP 地址,有一些地址被拿出来用于私有 IP 地址,以下不属于私有 IP 地址范围的是?

A: 10.6.207.84
B: 172.23.30.28
C: 172.32.50.80
D: 192.168.1.100

答案:C

属于 A 类的私有地址:
10.0.0.0 – 10.255.255.255
属于 B 类的私有地址:
172.16.0.0 – 172.31.255.255(记住是16-31)
属于 C 类的私有地址:
192.168.0.0 – 192.168.255.255

编程题

题1:左右最值最大差

给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0…K],右部分A[K+1…N-1],K 可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?

给定整数数组A和数组的大小n,请返回题目所求的答案

测试样例:
[2,7,3,1,1],5
返回:6

class MaxGap {
public:
    int findMaxGap(vector<int> A, int n) {
        vector<int>Max(n);
        vector<int>Min(n);
        Max[0] = A[0];
        for(int i = 1;i<n;++i){
            Max[i] = max(Max[i-1],A[i]);
        }
        Min[n-1] = A[n-1];
        for(int i = n-2;i>=0;--i){
            Min[i] = max(Min[i+1],A[i]);
        }
        int maxnum = 0;
        for(int i = 0;i<n;++i){
            maxnum = max(maxnum,abs(Max[i]-Min[i]));
        }
        return maxnum;
    }
};

题2:数据库连接池

Web系统通常会频繁地访问数据库,如果每次访问都创建新连接,性能会很差。为了提高性能,架构师决定复用已经创建的连接。当收到请求,并且连接池中没有剩余可用的连接时,系统会创建一个新连接,当请求处理完成时该连接会被放入连接池中,供后续请求使用。现在提供你处理请求的日志,请你分析一下连接池最多需要创建多少个连接。

  • 输入描述:输入包含多组数据,每组数据第一行包含一个正整n(1≤n≤1000),表示请求的数量。紧接着n行,每行包含一个请求编号id(A、B、C……、Z)和操作(connect或disconnect)。
  • 输出描述:对应每一组数据,输出连接池最多需要创建多少个连接。

输入
6
A connect
A disconnect
B connect
C connect
B disconnect
C disconnect
输出
2

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
using namespace std;
int main(){
	int n;
	while (cin >> n){
		set<string> pool;
		string id, con;
		int maxSize = 0;
		for (int i = 0; i < n; ++i){
			cin >> id >> con;
			if (con == "connect") {
				pool.insert(id);
			}else if (con == "disconnect"){
				pool.erase(id);
			}

			int size = pool.size();
			maxSize = max(maxSize, size);
		}
		cout << maxSize << endl;
	}
	return 0;
}
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main() {
	int n;
	char id;
	string str;
	while (cin >> n) {
		int sum = 0;
		int max = 0;
		for (int i = 0; i < n; ++i) {
			cin >> id >> str;
			if (str == "connect") {
				sum++;
				if (sum > max) {
					max = sum;
				}
			}
			else if (str == "disconnect") {
				--sum;
			}
		}
		cout << max << endl;
	}

	system("pause");
	return 0;
}

题3: mkdir

工作中,每当要部署一台新机器的时候,就意味着有一堆目录需要创建。例如要创建目录“/usr/local/bin”,就需要此次创建“/usr”、“/usr/local”以及“/usr/local/bin”。好在,Linux下mkdir提供了强大的“-p”选项,只要一条命令“mkdir -p /usr/local/bin”就能自动创建需要的上级目录。现在给你一些需要创建的文件夹目录,请你帮忙生成相应的“mkdir -p”命令。

  • 输入描述:输入包含多组数据。每组数据第一行为一个正整数 n (1≤n≤1024)。紧接着 n 行,每行包含一个待创建的目录名,目录名仅由数字和字母组成,长度不超过 200 个字符。

  • 输出描述:对应每一组数据,输出相应的、按照字典顺序排序的 “mkdir -p” 命令。每组数据之后输出一个空行作为分隔。

输入
3
/a
/a/b
/a/b/c
3
/usr/local/bin
/usr/bin
/usr/local/share/bin
输出
mkdir -p /a/b/c
mkdir -p /usr/bin
mkdir -p /usr/local/bin
mkdir -p /usr/local/share/bin

解题思路:如何去判断在什么时候应该递归创建,什么时候不应该递归创建?
而且该题还有一个问题就是:结果必须是按照字典序已经排好序的,这一点可以在输入的时候利用 sort 函数进行排序,然后再判断。

  1. 如果两个字符串是相同的则是重复创建

  2. 如果前一个是后一个的字串,且后一位还有一个 ‘/'字符,则已经说明这是应该要递归创建的

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main(){
	int n;
	while (cin >> n){
		vector<string> list(n);
		vector<bool> flag(n, true);
		for (int i = 0; i < n; ++i) {
			cin >> list[i];
		}
		sort(list.begin(), list.end());
		//将类似字符串经过排序,放在一起

		for (int i = 0; i < list.size() - 1; ++i){
			// 1、两串相同
			// 2、前串是后串的子串,而且后串后一位是 '/'
			if (list[i] == list[i + 1]) {
				flag[i] = false;
			}
			else if (list[i].size() < list[i + 1].size()
				&& list[i] == list[i + 1].substr(0, list[i].size())
				&& list[i + 1][list[i].size()] == '/')
			{
				flag[i] = false;
			}
		}

		for (int i = 0; i < list.size(); ++i) {
			if (flag[i]) {
				cout << "mkdir -p " << list[i] << endl;
			}
		}
		cout << endl;
	}
	return 0;
}

题4:顺时针打印矩阵

对于一个矩阵,请设计一个算法从左上角(mat[0][0])开始,顺时针打印矩阵元素。给定 int 矩阵 mat , 以及它的维数 nxm,请返回一个数组,数组中的元素为矩阵元素的顺时针输出

测试样例:
[[1,2],[3,4]],2,2
返回:[1,2,4,3]

方法一:一个矩形可以由左上角和右下角坐标定义,每次循环都要重新定位,在处理边界的时候会比较麻烦点

class Printer {
public:
    vector<int> clockwisePrint(vector<vector<int> > mat, int n, int m) {
        int x1 = 0,y1 = 0;
        int x2 = n-1,y2 = m-1;
        vector<int>v;
        while(x1<=x2 && y1<=y2){
            // 最上行的所有数据
            for(int i = y1;i<=y2;++i){
                v.push_back(mat[x1][i]);
            }
            // 最右行从 x1 + 1 开始,x2-1结束
            for(int i = x1+1;i<x2;++i){
                v.push_back(mat[i][y2]);
            }
            // 最下行的所有数据
            for(int i = y2;x2>x1 && i>=y1;--i){
                v.push_back(mat[x2][i]);
            }
            // 最左行从 x2-1 开始,x1+1  结束
            for(int i = x2-1;y2 > y1 && i > x1;--i){
                v.push_back(mat[i][y1]);
            }
            x1++;
            y1++;
            x2--;
            y2--;
        }
        return v;
    }
};

方法二:利用一个方向数组,当容器的值等于 m * n 时,返回容器数组

class Printer {
public:
    vector<int> clockwisePrint(vector<vector<int> > mat, int n, int m) {
        // 定义方向数组
        int dict[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
        vector<int>res;
        int i = 0,start = 0;
        int j = -1;
        while(1){
            int a = i + dict[start][0];
		    int b = j + dict[start][1];
		    if (!(0 <= a && a < n) ||
			    !(0 <= b && b < m) ||
			    mat[a][b] == INT_MAX) {
			    start = (start + 1) % 4;
		    }
            i += dict[start][0];
            j += dict[start][1];
            res.push_back(mat[i][j]);
            // 设置标记
            mat[i][j] = INT_MAX;
            if(res.size()== m*n){
                break;
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序猿的温柔香

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

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

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

打赏作者

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

抵扣说明:

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

余额充值