题目来源: 力扣(LeetCode)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 地址。
示例 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 split(string s, char c) {
vector 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 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 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



