[补题记录] VLAN配置信息

题意

二层转发设备的端口支持 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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值