【LeetCode】468. 验证IP地址

468. 验证IP地址


原题链接: 468. 验证IP地址

题目大意

给定一个字符串 queryIP。如果是有效的IPv4地址,返回 "IPv4" ;如果是有效的IPv6地址,返回 "IPv6" ;如果不是上述类型的IP地址,返回 "Neither"
有效的IPv4地址 是“x1.x2.x3.x4”形式的IP地址。 其中 0 <= xi <= 255 xi 不能包含 前导零。例如: “192.168.1.1” “192.168.1.0” 为有效IPv4地址, “192.168.01.1” 为无效IPv4地址; “192.168.1.00”“192.168@1.1” 为无效IPv4地址。
一个有效的IPv6地址 是一个格式为“x1:x2:x3:x4:x5:x6:x7:x8” 的IP地址,其中:

  • 1 <= xi.length <= 4
  • xi 是一个 十六进制字符串 ,可以包含数字、小写英文字母( 'a' 'f' )和大写英文字母('A''F' )。
  • xi 中允许前导零。

例如 "2001:0db8:85a3:0000:0000:8a2e:0370:7334" "2001:db8:85a3:0:0:8A2E:0370:7334" 是有效的 IPv6 地址,而 "2001:0db8:85a3::8A2E:037j:7334" "02001:0db8:85a3:0000:0000:8a2e:0370:7334" 是无效的 IPv6 地址。

示例:

输入:queryIP = "172.16.254.1"
输出:"IPv4"
解释:有效的 IPv4 地址,返回 "IPv4"
输入:queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
输出:"IPv6"
解释:有效的 IPv6 地址,返回 "IPv6"
输入:queryIP = "256.256.256.256"
输出:"Neither"
解释:既不是 IPv4 地址,又不是 IPv6 地址

queryIP 仅由英文字母,数字,字符 '.' 和 ':' 组成。

思路

比较复杂的模拟,按要求不断完善。
首先若字符串同时含有’.‘与’:‘则无效,含有单个时分别判断是否为IPv4/IPv6,否则无效。
在判断IPv4/IPv6时,首先实现split函数,将字符串以’.‘或’:'进行分割,采用了双指针算法。

  1. 对IP分段后,判断段数是否满足,IPv4为4段,IPv6为8段。
  2. 对于IPv4,分割后的每段字符串应满足:
    1.长度为1~3
    2.不含前导0
    3.每一字符都为数字,再去判断范围是否在0~255内
    对于IPv6,分割后的每段字符串应满足:
    1.长度为1~4
    2.每一字符都为字母(小写英文字母( 'a' 'f' )和大写英文字母('A''F' ))或数字。

其中,在split函数应用时,应在原字符串上加上’.‘或’:‘(split(ip + ':', ':')),原因在于某些测试案例如图所示:
最后执行的输入: "2001:0db8:85a3:0:0:8A2E:0370:7334:"
在这里插入图片描述
此时字符串最后一个字符为’:‘,但无论最后一个字符’:‘是否存在,split输出的效果一致,等价于去除’:'而认为其是IPv6。
因此,split(ip + ':', ':')会使该情况得到的size()为9(多出一个空字符串),从而正确判断分割后的段数,输出"Neither"。

代码

class Solution {
public:
    vector<string> split(string ip, char c){
        vector<string> res;

        for(int i = 0; i < ip.size(); i ++ ){
            int j = i;
            string s;
            while(ip[j] != c && j < ip.size()) s += ip[j ++ ];
            res.push_back(s);
            i = j;
        }

        return res;
    }

    bool check(char c){
        if(c >= '0' && c <= '9') return true;
        if(c >= 'A' && c <= 'F') return true;
        if(c >= 'a' && c <= 'f') return true;
        return false;
    }

    string check_ipv4(string ip){
        auto items = split(ip + '.', '.');
        if(items.size() != 4) return "Neither"; // 段数
        for(auto item : items){
            if(item.empty() || item.size() > 3) return "Neither"; // 长度
            if(item.size() > 1 && item[0] == '0') return "Neither"; // 前导0
            // 每一字符都为数字
            for(char c : item){
                if(c < '0' || c > '9') return "Neither";
            }
            // 取值范围
            int t = stoi(item);
            if(t > 255) return "Neither";
        }

        return "IPv4";
    }

    string check_ipv6(string ip){
        auto items = split(ip + ':', ':');
        if(items.size() != 8) return "Neither"; // 段数
        for(auto item : items){
            if(item.empty() || item.size() > 4) return "Neither"; // 每段长度为1~4
            // 每个字符应为字符或数字
            for(char c : item){
                if(!check(c)) return "Neither";
            }
        }

        return "IPv6";
    }

    string validIPAddress(string ip) {
        if(ip.find('.') != -1 && ip.find(':') != -1) return "Neither";
        cout << split(ip, ':').size();

        if(ip.find('.') != -1) return check_ipv4(ip);
        if(ip.find(':') != -1) return check_ipv6(ip);
        return "Neither";
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值