【华为OD-E卷 - VLAN资源池 100分(python、java、c++、js、c)】
【华为OD-E卷 - VLAN资源池 100分(python、java、c++、js、c)】
题目
VLAN是一种对局域网设备进行逻辑划分的技术,为了标识不同的VLAN,引入VLAN ID(1-4094之间的整数)的概念。
定义一个VLAN ID的资源池(下称VLAN资源池),资源池中连续的VLAN用开始VLAN-结束VLAN表示,不连续的用单个整数表示,所有的VLAN用英文逗号连接起来。
现在有一个VLAN资源池,业务需要从资源池中申请一个VLAN,需要你输出从VLAN资源池中移除申请的VLAN后的资源池。
输入描述
- 第一行为字符串格式的VLAN资源池,第二行为业务要申请的VLAN,VLAN的取值范围为[1,4094]之间的整数
输出描述
- 从输入VLAN资源池中移除申请的VLAN后字符串格式的VLAN资源池,输出要求满足题目描述中的格式,并且按照VLAN从小到大升序输出。
如果申请的VLAN不在原VLAN资源池内,输出原VLAN资源池升序排序后的字符串即可
备注
- 输入VLAN资源池中VLAN的数量取值范围为[2-4094]间的整数,资源池中VLAN不重复且合法([1,4094]之间的整数),输入是乱序的
用例
用例一:
输入:
1-5
2
输出:
1,3-5
用例二:
输入:
20-21,15,18,30,5-10
15
输出:
5-10,18,20-21,30
用例三:
输入:
5,1-3
10
输出:
1-3,5
说明 原VLAN资源池中有VLAN 1、2、3,5,申请的VLAN 10不在原资源池中,将原资源池按照题目描述格式并按升序排序后输出的结果
python解法
- 解题思路:
- 问题描述:
任务是解析用户输入的 VLAN 列表(格式可能为单个数字或范围,如 1,3-5,8),将其转换为有序的 VLAN 列表。
支持删除指定的 VLAN,并输出删除后的结果,结果需重新格式化为范围形式。
输入输出要求:
输入:
第一行:VLAN 列表字符串,格式为单个数字或范围的组合,用逗号分隔。
第二行:要删除的单个 VLAN。
输出:
删除后的 VLAN 列表,按范围格式输出。
具体实现:
解析 VLAN 列表:
对输入字符串按逗号分割。
如果片段中包含 -,解析为范围,并将范围内的数字逐个添加到列表中。
否则,将单个数字直接添加到列表中。
最终返回排序后的 VLAN 列表。
格式化 VLAN 列表:
将连续的数字合并为范围(如 [3, 4, 5] 合并为 3-5)。
非连续的数字单独输出。
删除 VLAN:
检查指定的 VLAN 是否在解析后的列表中。
如果存在,移除该 VLAN。
输出结果:
使用格式化函数将修改后的列表转换回范围形式并输出
# 解析 VLAN 字符串为一个有序的整数列表
def parse_vlans(vlan_str):
vlans = [] # 用于存储解析后的 VLAN 数字
# 将输入字符串按逗号分割
for part in vlan_str.split(','):
if '-' in part: # 如果是一个范围(例如 "3-5")
# 按 '-' 分割,并将范围的起始和结束值转换为整数
start, end = map(int, part.split('-'))
# 将范围内的所有数字添加到 VLAN 列表中
vlans.extend(range(start, end + 1))
else: # 如果是单个数字
vlans.append(int(part)) # 将数字添加到 VLAN 列表
return sorted(vlans) # 返回排序后的 VLAN 列表
# 将整数 VLAN 列表格式化为范围字符串
def format_vlans(vlans):
result = [] # 用于存储格式化后的范围字符串
i = 0
# 遍历 VLAN 列表
while i < len(vlans):
start = vlans[i] # 当前范围的起始值
# 检查后续的数字是否连续
while i + 1 < len(vlans) and vlans[i + 1] == vlans[i] + 1:
i += 1
end = vlans[i] # 当前范围的结束值
# 如果起始值和结束值相同,说明是单个数字
if start == end:
result.append(f"{start}")
else: # 否则,格式化为范围字符串
result.append(f"{start}-{end}")
i += 1 # 移动到下一个数字
return ",".join(result) # 返回用逗号分隔的范围字符串
# 主程序逻辑
# 第一步:解析输入的 VLAN 列表
vlan_pool = parse_vlans(input()) # 从输入读取 VLAN 字符串并解析为列表
# 第二步:读取需要删除的 VLAN
to_remove = int(input()) # 读取要删除的 VLAN
# 第三步:从 VLAN 列表中移除指定 VLAN(如果存在)
if to_remove in vlan_pool:
vlan_pool.remove(to_remove)
# 第四步:格式化并输出修改后的 VLAN 列表
print(format_vlans(vlan_pool)) # 输出结果
java解法
- 解题思路
- 问题描述:
输入一个 VLAN 范围池(如 1,3-5,8),表示 VLAN 的集合。
用户输入一个待移除的 VLAN(如 4)。
从 VLAN 池中删除指定的 VLAN 后,输出更新后的 VLAN 范围,格式与输入保持一致。
输入输出:
输入:
第一行是以逗号分隔的 VLAN 池,可以包含单个数字或范围(如 1,3-5,8)。
第二行是待删除的单个 VLAN(如 4)。
输出:
更新后的 VLAN 范围池,按逗号分隔,格式化为单个数字或范围。
实现步骤:
解析输入:
将第一行的 VLAN 池字符串分割为片段。
解析每个片段,单个数字直接转为范围 [start, start],范围用 [start, end] 表示。
处理删除操作:
遍历解析后的范围池,检查指定的 VLAN 是否在某个范围内。
如果在范围内:
移除当前范围。
根据需要拆分为两个新的范围(即将指定 VLAN 从范围中移除)。
格式化输出:
遍历更新后的范围池,将单个数字和范围分别格式化为字符串。
使用逗号拼接为最终输出。
关键点:
解析范围的逻辑:
例如,3-5 解析为 [3, 5]。
单个数字 8 解析为 [8, 8]。
删除指定 VLAN 的逻辑:
如果指定 VLAN 位于某个范围中:
删除原范围。
如果 VLAN 是范围的起点或终点,更新范围的边界。
如果 VLAN 位于范围中间,拆分为两个范围
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取输入并解析 VLAN 池(逗号分隔)
String[] inputArr = sc.nextLine().split(",");
// 读取需要删除的 VLAN
int reqVlan = Integer.parseInt(sc.nextLine());
// 调用解决函数并打印结果
System.out.println(solve(inputArr, reqVlan));
}
/**
* 解决 VLAN 范围池处理问题
*
* @param pool 输入的 VLAN 池(数组形式,每个元素为范围或单个数字)
* @param reqVlan 需要删除的 VLAN
* @return 更新后的 VLAN 池(字符串格式)
*/
public static String solve(String[] pool, int reqVlan) {
// 用于存储解析后的 VLAN 范围
List<int[]> vlanList = new ArrayList<>();
// 解析输入的 VLAN 池
for (String part : pool) {
// 分割范围字符串(如 "3-5" 或 "8")
String[] range = part.split("-");
int start = Integer.parseInt(range[0]); // 起始值
int end = range.length > 1 ? Integer.parseInt(range[1]) : start; // 结束值
vlanList.add(new int[]{start, end}); // 添加范围到列表
}
// 按起始值对范围列表排序
vlanList.sort(Comparator.comparingInt(a -> a[0]));
// 遍历范围池,检查并处理要删除的 VLAN
for (int i = 0; i < vlanList.size(); i++) {
int[] vlan = vlanList.get(i); // 当前范围
// 如果指定的 VLAN 在当前范围内
if (reqVlan >= vlan[0] && reqVlan <= vlan[1]) {
vlanList.remove(i); // 移除当前范围
// 如果指定 VLAN 位于范围的中间,拆分为两个范围
if (vlan[0] < reqVlan) vlanList.add(i, new int[]{vlan[0], reqVlan - 1}); // 前部分
if (vlan[1] > reqVlan) vlanList.add(i, new int[]{reqVlan + 1, vlan[1]}); // 后部分
break; // 删除完成后退出循环
}
}
// 将更新后的范围池格式化为字符串
List<String> result = new ArrayList<>();
for (int[] range : vlanList) {
// 如果范围是单个数字
if (range[0] == range[1]) result.add(String.valueOf(range[0]));
else result.add(range[0] + "-" + range[1]); // 否则格式化为范围
}
// 返回用逗号分隔的范围字符串
return String.join(",", result);
}
}
C++解法
- 解题思路
更新中
C解法
更新中
JS解法
更新中
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/525549.html 如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!