【华为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 += 1end = 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(",");// 读取需要删除的 VLANint 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]));// 遍历范围池,检查并处理要删除的 VLANfor (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解法
更新中
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏