【468. 验证IP地址】

题目来源: 力扣(LeetCode)468. 验证IP地址

描述

给定一个字符串 queryIP。如果是有效的 IPv4 地址,返回 "IPv4" ;如果是有效的 IPv6 地址,返回 "IPv6" ;如果不是上述类型的 IP 地址,返回 "Neither"

有效的IPv4地址“x1.x2.x3.x4” 形式的IP地址。 其中 0 <= xi <= 255xi 不能包含 前导零。例如: “192.168.1.1”“192.168.1.0” 为有效IPv4地址, “192.168.01.1” 为无效IPv4地址; “192.168.1.00”[email protected] 为无效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 地址

示例 1:

输入:queryIP = "172.16.254.1"
输出:"IPv4"
解释:有效的 IPv4 地址,返回 "IPv4"

示例 2:

输入:queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
输出:"IPv6"
解释:有效的 IPv6 地址,返回 "IPv6"

示例 3:

输入:queryIP = "256.256.256.256"
输出:"Neither"
解释:既不是 IPv4 地址,又不是 IPv6 地址

解题思路

总体思路,给定的字符串先分割,再判断。

IPv4以’.‘分割、IPv6以’:'分割,把分割字串加入数组

IPv4的判断主要有:

  • 先看返回子串vector元素个数,不是4个return false;
  • 再判断每个字串,如果字串长度为0、或者大于3,return false;
  • 判断非0字串是否有前置0,如果有,return false;
  • 判断子串中是否包含除数字外的字符,如果有,return false;
  • 再判断是否越界,如果有返回false;
    否则,返回true;

IPv6的判断:

  • 先看返回子串vector元素的个数,如果不为8,return false;
  • 再看每个子串长度,如果为0或者大于4,return false;
  • 再判断每个子串,只允许含有0-9,a-f,A-F的字符,如果含有其他,则返回false
    否则,返回true;

再更具返回的bool值判断是IPv4还是IPv6。

代码:

class Solution {
public:
    vector<string> split(string s, char c) {
        vector<string> res = {};
        int l = 0;
        for (int r = 0; r < s.length(); r++) {
            if (s[r] == c) {
                // split
                string temp = s.substr(l, r - l);
                res.push_back(temp);
                l = r + 1;
            }
        }
        res.push_back(s.substr(l, s.length() - l));
        return res;
    }
    
    bool validIPv4(string s) {
        vector<string> v = split(s, '.');
        // ipv4是4个
        if (v.size() != 4) return false;
        for (int i = 0; i < v.size(); i++) {
            string cur = v[i];
            int len = cur.length();
            // 长度问题
            if (len == 0 || len > 3) return false;
            // 非单一0,false
            if (cur[0] == '0' && len != 1) return false;
            // 不是只包含数字, false
            for (int j = 0; j < len; j++) {
                if (cur[j] >= '0' && cur[j] <= '9') continue;
                else return false;
            }
            // 是否越界
            if (stoi(cur) < 0 || stoi(cur) > 255) return false;
        }
        return true;
    }

    bool validIPv6(string s) {
        vector<string> v = split(s, ':');
        // ipv6是8个
        if (v.size() != 8) return false;
        for (int i = 0; i < v.size(); i++) {
            string cur = v[i];
            // 长度限制
            if (cur.length() == 0 || cur.length() > 4) return false;
            // 只准包含0-9,a-f,A-F
            for (int j = 0; j < cur.length(); j++) {
                if ((cur[j] >= '0' && cur[j] <= '9') || (cur[j] >= 'a' && cur[j] <= 'f') || (cur[j] >= 'A' && cur[j] <= 'F')) {
                    continue;
                } else {
                    return false;
                }
            }
        }
        return true;
    }

    string validIPAddress(string queryIP) {
        bool isIPv4 = validIPv4(queryIP);
        bool isIPv6 = validIPv6(queryIP);
        if (isIPv4) return "IPv4";
        if (isIPv6) return "IPv6";
        return "Neither";
    }
};

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:6.5 MB, 在所有 C++ 提交中击败了15.49%的用户
通过测试用例:
73 / 73

你可能感兴趣的:(LeetCode,tcp/ip,leetcode,网络协议)