VLAN资源池
题目描述
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资源池升序排序后的字符串即可.
示例1
输入:
1-5
2
输出:
1,3-5
说明:
原VLAN资源池中有VLAN 1/2/3/4/5, 从资源池中移除2后, 剩下VLAN 1/3/4/5, 按照题目描述格式并升序后的结果为 1,3-5
示例2
输入:
20-21,15,18,30,5-10
15
输出:
5-10,18,20-21,30
说明:
原VLAN资源池中有VLAN 5/6/7/8/9/10/15/18/20/21/30, 从资源池中移除15后, 资源池中剩下的VLAN为
5/6/7/8/9/10/18/20/21/30, 按照题目描述格式并升序后的结果为 5-10,18,20-21,30
.
示例3
输入:
5,1-3
10
输出:
1-3,5
题解
Python
def main():
# 读取输入
# 解析当前所有的 VLAN ID, 并存储到集合或者数组中
# 然后移除指定的 ID
# 最后新剩下的 ID 格式化输出
parts = input().split(",")
id_set = set()
for part in parts:
if "-" in part:
range_part = part.split("-")
start_id = int(range_part[0])
end_id = int(range_part[1])
for vlan_id in range(start_id, end_id + 1):
assert 1 <= vlan_id <= 4094
id_set.add(vlan_id)
else:
vlan_id = int(part)
assert 1 <= vlan_id <= 4094
id_set.add(vlan_id)
assert id_set
removed_id = int(input())
if removed_id in id_set:
id_set.remove(removed_id)
# 格式化输出
# 先转换成列表, 再排序
id_list = list(id_set)
id_list.sort()
start_id = -1
last_id = -1
out = []
for vlan_id in id_list:
if last_id + 1 == vlan_id:
# 连续 ID
last_id = vlan_id
else:
# 重置连续 ID
if last_id == -1:
pass
elif last_id == start_id:
# 单个值
out.append(str(last_id))
else:
# 范围
out.append(F"{start_id}-{last_id}")
start_id = vlan_id
last_id = vlan_id
# 处理最后一个元素
if last_id == start_id:
# 单个值
out.append(str(last_id))
else:
# 范围
out.append(F"{start_id}-{last_id}")
# 打印结果
print(",".join(out))
if __name__ == "__main__":
main()
Rust
use std::collections::HashSet; use std::io::{stdin, BufRead}; fn solution() { // 读取输入 // 解析当前所有的 VLAN ID, 并存储到集合或者数组中 // 然后移除指定的 ID // 最后新剩下的 ID 格式化输出 let mut line = String::new(); let ret = stdin().lock().read_line(&mut line); assert!(ret.is_ok()); let mut id_set = HashSet::<u32>::new(); for part in line.trim().split(",") { if part.contains("-") { let mut range_part = part.split("-"); let start_id: u32 = range_part.next().unwrap().parse().unwrap(); let end_id: u32 = range_part.next().unwrap().parse().unwrap(); assert!(range_part.next().is_none()); for vlan_id in start_id..=end_id { assert!((1..=4094).contains(&vlan_id)); id_set.insert(vlan_id); } } else { let vlan_id: u32 = part.parse().unwrap(); assert!((1..=4094).contains(&vlan_id)); id_set.insert(vlan_id); } } assert!(!id_set.is_empty()); line.clear(); let ret = stdin().lock().read_line(&mut line); assert!(ret.is_ok()); let removed_id: u32 = line.trim().parse().unwrap(); id_set.remove(&removed_id); // 格式化输出 // 先转换成列表, 再排序 let mut id_list: Vec<u32> = id_set.into_iter().collect(); id_list.sort_unstable(); let mut start_id = u32::MAX; let mut last_id = u32::MAX; let mut out = Vec::new(); for &vlan_id in &id_list { if vlan_id - 1 == last_id { // 连续 ID last_id = vlan_id; } else { // 重置连续 ID if last_id == u32::MAX { // 忽略 } else if last_id == start_id { // 单个值 out.push(last_id.to_string()); } else { // 范围 out.push(format!("{start_id}-{last_id}")); } start_id = vlan_id; last_id = vlan_id; } } // 处理最后一个元素 if last_id == start_id { // 单个值 out.push(last_id.to_string()); } else { // 范围 out.push(format!("{start_id}-{last_id}")); } // 打印结果 println!("{}", out.join(",")); } fn main() { solution(); }
C++
#include <iostream>
#include <string>
#include <sstream>
#include <unordered_set>
#include <vector>
int main() {
// 读取输入
// 解析当前所有的 VLAN ID, 并存储到集合或者数组中
// 然后移除指定的 ID
// 最后新剩下的 ID 格式化输出
std::string line;
std::getline(std::cin, line);
std::vector<int> id_list;
std::stringstream ss(line);
std::getline(std::cin, line);
const int removed_id = std::stoi(line);
while (std::getline(ss, line, ',')) {
std::cout << "line: " << line << std::endl;
const int index = line.find('-');
if (index == std::string::npos) {
const int vlan_id = std::stoi(line);
id_list.push_back(vlan_id);
} else {
const std::string start = line.substr(0, index);
const int start_id = std::stoi(start);
const std::string end = line.substr(index + 1);
const int end_id = std::stoi(end);
for (int vlan_id = start_id; vlan_id <= end_id; ++vlan_id) {
id_list.push_back(vlan_id);
}
}
}
// 排序
std::sort(id_list.begin(), id_list.end());
// 移除指定的 ID
auto removed_id_iter = std::find(id_list.begin(), id_list.end(), removed_id);
if (removed_id_iter != id_list.end()) {
id_list.erase(removed_id_iter);
}
int start_id = -1;
int last_id = -1;
std::vector<std::string> out;
const size_t kBufLen = 64;
char buf[kBufLen + 1];
for (int vlan_id : id_list) {
if (last_id + 1 == vlan_id) {
// 连续 ID
last_id = vlan_id;
} else {
// 重置连续 ID
if (last_id == -1) {
// pass
} else if (last_id == start_id) {
// 单个值
out.push_back(std::to_string(start_id));
} else {
// 范围
const int s_len = snprintf(buf, kBufLen, "%d-%d", start_id, last_id);
out.emplace_back(buf, s_len);
}
start_id = vlan_id;
last_id = vlan_id;
}
}
// 处理最后一个元素
if (last_id == start_id) {
// 单个值
out.push_back(std::to_string(start_id));
} else{
// 范围
const int s_len = snprintf(buf, kBufLen, "%d-%d", start_id, last_id);
out.emplace_back(buf, s_len);
}
for (int index = 0; index + 1 < out.size(); ++index) {
std::cout << out[index] << ",";
}
std::cout << out[out.size() - 1] << std::endl;
return 0;
}