「这是我参与2022首次更文挑战的第34天,活动详情查看:2022首次更文挑战」
1、题目
给定一个字符串 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”
、“[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::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
是无效的。
示例 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 地址
复制代码
提示:
queryIP
仅由英文字母,数字,字符'.'
和':'
组成。
2、思路
(字符串 + 模拟) O(n)
一个合法的IPv4满足以下条件:
- 被
.
分割成4
组字符串。 - 每组字符串不为空,且长度
<= 3
。 - 每组字符串转换成数字后介于
0 ~ 255
之间。 - 每组字符串仅由数字字符组成。
- 每组字符串的长度大于
1
时,不包含前导0
。
一个合法的IPv6满足以下条件:
- 被
:
分割成8
组字符串。 - 每组字符串不为空,且长度
<= 4
。 - 每组字符串转化成数字后为一个16进制数,即字符范围为:
0~9
,a~f
,A~F
。
由于C++中没有按字符分割的函数,因此我们自定义一个分割函数split
,如下:
vector<string> split(string ip, char t) {
vector<string> items;
for (int i = 0; i < ip.size(); i ++ ) {
int j = i;
string item;
while (ip[j] != t) item += ip[j ++ ];
i = j;
items.push_back(item);
}
return items;
}
复制代码
这里使用了双指针算法,传入一个要分割的字符串ip
和分割字符t
,最后返回分割好的字符串数组items
。
判断一个合法的IPv4和IPv6,我们首先调用分割函数split
,然后按照上述条件模拟即可。
具体过程如下:
- 1、如果一个字符串
ip
即包含.
也包含:
,我们直接返回Neither
。 - 2、如果包含
.
,我们进行check_ipv4(ip)
,IPv4的合法性判断。 - 3、如果包含
:
,我们进行check_ipv6(ip)
,IPv6的合法性判断。
时间复杂度分析: 每个字符串仅会被遍历一遍,因此时间复杂度为O(n)。
3、c++代码
class Solution {
public:
vector<string> split(string ip, char t){
vector<string> items;
for(int i = 0; i < ip.size(); i++){
int j = i;
string item;
while(j < ip.size() && ip[j] != t) item += ip[j++];
i = j;
items.push_back(item);
}
return items;
}
string check_ipv4(string ip){
auto items = split(ip + '.', '.');a
if(items.size() != 4) return "Neither";
for(string item : items){
if(item.empty() || item.size() > 3) return "Neither";
if(item.size() > 1 && item[0] == '0') return "Neither";
for(char c : item){
if(c < '0' || c > '9') return "Neither";
}
int t = stoi(item);
if(t > 255) return "Neither";
}
return "IPv4";
}
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_ipv6(string ip){
auto items = split(ip + ':', ':');
if(items.size() != 8) return "Neither";
for(string item : items){
if(item.empty() || item.size() > 4) return "Neither";
for(char c : item){
if(!check(c)) return "Neither";
}
}
return "IPv6";
}
string validIPAddress(string ip) {
if(ip.find('.') != -1 && ip.find(':') != -1) return "Neither";
if(ip.find('.') != -1) return check_ipv4(ip);
if(ip.find(':') != -1) return check_ipv6(ip);
return "Neither";
}
};
复制代码
4、Java代码
public String validIPAddress(String ip) {
if (ip.indexOf('.') != -1 && ip.indexOf(':') != -1) return "Neither";
if (ip.indexOf('.') != -1) return checkIPv4(ip);
if (ip.indexOf(':') != -1) return checkIPv6(ip);
return "Neither";
}
private String checkIPv4(String ip) {
String[] items = ip.split("\\.");
if (items.length != 4 || ip.charAt(ip.length() - 1) == '.') return "Neither";
for (String item : items) {
if (item.isEmpty() || item.length() > 3) return "Neither";
if (item.length() > 1 && item.charAt(0) == '0') return "Neither";
for (int i = 0; i < item.length(); i++)
if (item.charAt(i) < '0' || item.charAt(i) > '9') return "Neither";
int t = Integer.parseInt(item);
if (t > 255) return "Neither";
}
return "IPv4";
}
private String checkIPv6(String ip) {
String[] items = ip.split(":");
if (items.length != 8 || ip.charAt(ip.length() - 1) == ':') return "Neither";
for (String item : items) {
if (item.isEmpty() || item.length() > 4) return "Neither";
for (int i = 0; i < item.length(); i++)
if (!check(item.charAt(i))) return "Neither";
}
return "IPv6";
}
private boolean 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;
}
复制代码