题意
二层转发设备的端口支持 vlan , vlan-id 的配置仅支持两种命令,格式为:
-
port trunk allow-pass vlan <vlan-id>
– 配置允许通过的 vlan-id -
undo port trunk allow-pass vlan <vlan-id>
– 配置不允许通过的 vlan-id (命令中的undo 表示不允许)
其中<vlan-id>
有三种: -
单个 vlan-id:如
10
; -
vlan-id 区间:用
to
连接两 id 来表示,格式为id1 to id2
(id1 < id2,左闭右闭),如10 to 11
; -
任意多个以上两种组合,之间用单个空格分隔,如
10 20 to 22 12
,表示 10, 12, 20, 21, 22。
所有 vlan-id 在初始状态下均为不允许通过状态。现用户针对某一端口输入一组命令 cmds
,用于配置该端口的 vlan-id。请按输入顺序依次处理,最后转化成一条等效最简的命令,转化要求如下:
- 里的所有单个 vlan-id 值和 vlan-id 区间之间都没有重叠,且按 vlan-id 从小到大排列;
- 所有连续的 vlan-id 范围全部表示成 vlan-id 区间,如 8 和 9 需要表示成 8 to 9 。
注:用例保证最终允许通过的 vlan-id 至少一个。
解答要求
时间限制: C/C++ 1000ms, 其他语言:2000ms
内存限制: C/C++ 256MB, 其他语言:512MB
输入
1 <= cmds.length <= 100, 单条命令长度不超过 255,1 <= vlan-id <= 4095
输入保证每条命令格式合法(命令中的 vlan-id 为十进制整数),且单条配置命令里 vlan-id 无重复。
输出
用例保证输出长度不超过255,格式同“配置允许通过的 vlan-id” 的命令
样例1
输入:
[“port trunk allow-pass vlan 10 20 to 30”,
“port trunk allow-pass vlan 15 to 25 9”,
“undo port trunk allow-pass vlan 10 to 20 23”]
输出:
“port trunk allow-pass vlan 9 21 to 22 24 to 30”
解释:
第一条命令后,允许通过的vlan-id为:10, [20,30]
第二条命令后,允许通过的vlan-id为:[9,10], [15,30]
第三条命令后,允许通过的vlan-id为:9, [21,22], [24,30]
样例2
输入:
[“undo port trunk allow-pass vlan 10 to 20”,
“port trunk allow-pass vlan 17 to 20 24 to 4094”,
“port trunk allow-pass vlan 21 to 24”,
“port trunk allow-pass vlan 1 to 15 4095 16”]
输出:
“port trunk allow-pass vlan 1 to 4095”
解释:
vlan-id 从1到4095都允许通过
代码
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
string MergeCmds(const vector<string>& cmds)
{
std::string ans = "port trunk allow-pass vlan";
std::vector <int> pre(5000);
for (auto &str : cmds) {
std::string t;
bool flag = true;
for (int i = 0; i < str.length(); ++ i) {
if (str.substr(0, i) == "port trunk allow-pass vlan " || str.substr(0, i) == "undo port trunk allow-pass vlan ") {
if (str.substr(0, 4) == "undo") flag = false;
t = str.substr(i, str.length() - i);
break;
}
}
std::vector<std::string> vs;
for (int i = 0; i < t.length(); ++ i) {
std::string num;
if (t[i] != ' ') {
for (int j = i; j < t.length(); ++ j) {
if (j + 1 >= t.length() || t[j + 1] == ' ') {
num = t.substr(i, j - i + 1);
i = j + 1;
break;
}
}
}
vs.push_back(num);
}
bool hasLast = false;
std::string lastStr;
for (auto &num : vs) {
if (num == "to") {
hasLast = true;
} else {
int now = std::stoi(num);
if (hasLast) {
int lastNum = std::stoi(lastStr);
for (int i = lastNum; i <= now; ++ i) {
pre[i] = flag ? 1 : 0;
}
//std::cout << lastNum << " " << now << "\n";
hasLast = false;
} else {
pre[now] = flag ? 1 : 0;
//std::cout << now << "\n";
}
lastStr = num;
}
}
}
for (int i = 1; i <= 4100; ++ i) {
if (pre[i] == 1) {
int l = i, r = i;
for (int j = i + 1; j <= 4100; ++ j) {
if (pre[j] == 1) r = j;
else {
i = j;
break;
}
}
if (l == r) ans = ans + " " + std::to_string(l);
else ans = ans + " " + std::to_string(l) + " to " + std::to_string(r);
}
}
return ans;
}
};