编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。
如果是有效的 IPv4 地址,返回 "IPv4" ;
如果是有效的 IPv6 地址,返回 "IPv6" ;
如果不是上述类型的 IP 地址,返回 "Neither" 。
IPv4 地址由十进制数和点来表示,每个地址包含 4 个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;
同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
IPv6 地址由 8 组 16 进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。
示例 1:
输入:IP = "172.16.254.1"
输出:"IPv4"
解释:有效的 IPv4 地址,返回 "IPv4"
示例 2:
输入:IP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
输出:"IPv6"
解释:有效的 IPv6 地址,返回 "IPv6"
示例 3:
输入:IP = "256.256.256.256"
输出:"Neither"
解释:既不是 IPv4 地址,又不是 IPv6 地址
示例 4:
输入:IP = "2001:0db8:85a3:0:0:8A2E:0370:7334:"
输出:"Neither"
示例 5:
输入:IP = "1e1.4.5.6"
输出:"Neither"
提示:
IP 仅由英文字母,数字,字符 '.' 和 ':' 组成。
题目链接:https://leetcode.com/problems/validate-ip-address/submissions/
思路:
IPV4:
1.判断是不是4部分
2.每一小部分长度是不是在0-3之间
3.每一小部分的每个字符是不是都是数字
4.每一部分的数字是不是在0-255之间
IPV6:
1.判断是不是8部分
2.判断是不是在0-4之间
3.判断每一小部分是不是只包含 数字和字母 !(isdigit(c)||(c>='a'&&c<='f')||(c>='A'&&c<='F'))整体取反
class Solution {
public:
string validIPAddress(string IP) {
if(IP.size()<1)
return "Neither";
if (isIPV4(IP)) return "IPv4";
else if (isIPV6(IP)) return "IPv6";
return "Neither";
}
void split(string ip,vector<string> &vc,char delim)
{
// istringstream is(ip);
// string value;
// while(getline(is,value,delim)){
// vc.push_back(value);
// }
// if(!ip.empty()&&ip.back()==delim)
// {
// vc.push_back({});
// }
int len=ip.size();
string tmp="";
for(int i=0;i<len;i++)
{
if(ip[i]!=delim)
{
tmp+=ip[i];
}
else
{
vc.push_back(tmp);
tmp="";
}
}
if(tmp!="")//1.1.1.2 压入最后一个‘2’
{
vc.push_back(tmp);
}
if(ip[len-1]==delim)//例子里有最后一个字符是‘:’,不是合法的IPV6
{
vc.push_back({});
}
}
bool isIPV4(string ip)
{
vector<string> vc;
split(ip,vc,'.');
if(vc.size()!=4)
{
// cout<<"aaa";
return false;
}
for(auto v:vc)
{
if(v.size()==0||v.size()>3)
{
// cout<<"bbb";
return false;
}
if(v.size()>1&&v[0]=='0')//开头不能是‘0’
{
// cout<<"ccc";
return false;
}
for(auto c:v)
{
if(!isdigit(c))//不是数字返回false
{
// cout<<"ddd";
return false;
}
}
int n=stoi(v);
if(n<0||n>255)
{
// cout<<"eee";
return false;
}
}
return true;
}
bool isIPV6(string ip)
{
vector<string> vc;
split(ip,vc,':');
if(vc.size()!=8)
{
return false;
}
for(auto v:vc)
{
if(v.size()==0||v.size()>4)
{
cout<<"aaaa";
return false;
}
for(auto c:v)
{
if(!(isdigit(c)||(c>='a'&&c<='f')||(c>='A'&&c<='F')))//整体取反,不是数字,不是字母false
{
cout<<"bbbb";
return false;
}
}
// int n=stoi(v);
// if(v<0||v>255)
// {
// return false;
// }
}
return true;
}
};
#include<bits/stdc++.h>
class Solution {
public:
/**
* 验证IP地址
* @param IP string字符串 一个IP地址字符串
* @return string字符串
*/
bool typev6(string IP)
{
for(auto it:IP)
{
if(it=='.')
{
return false;
}
}
return true;
}
vector<string> split(string s,char c)
{
string tmp="";
vector<string> res;
for(int i=0;i<s.size();i++)
{
if(s[i]==c)
{
if(tmp.size()>0)
{
res.push_back(tmp);
tmp="";
}
}
else
{
tmp+=s[i];
}
}
if(tmp.size()>0)
{
res.push_back(tmp);
}
return res;
}
/*
判断v6步骤:
1.先看是不是8个部分
2.判断每个部分的长度是不是 4
3.检查每一个小部分的字符是不是在0-9 a-f A-F 之间
*/
bool checkv6(string IP)
{
vector<string> res=split(IP,':');
if(res.size()!=8)
return false;
for(int i=0;i<res.size();i++)
{
if(res[i].size()>4)
{
return false;
}
else
{
string tmp=res[i];
int cnt=0;
for(int j=0;j<tmp.size();j++)
{
if(!(tmp[j]>='0'&&tmp[j]<='9' || tmp[j]>='a'&&tmp[j]<='f' || tmp[j]>='A'&&tmp[j]<='F'))
{
return false;
}
}
}
}
return true;
}
/*
判断合法IPv4步骤:
1.先看是不是4个部分
2.判断每个部分的数值是不是在0-255 且 注意检查 01这种情况
tips:这题还不够严谨,用stoi,对于 2a4 这种非法的检查不出来
*/
bool checkv4(string IP)
{
vector<string> res=split(IP,'.');
if(res.size()!=4)
return false;
for(int i=0;i<res.size();i++)
{
for(auto it:res[i])
{
if(!(it>='0'&&it<='9'))//严谨点
{
return false;
}
}
if(!(stoi(res[i])>=0&&stoi(res[i])<=255) || (res[i].size()>1&&res[i][0]=='0'))
{
return false;
}
}
return true;
}
string solve(string IP) {
// write code here
// cout<<stoi("2a4")<<endl;
if(typev6(IP))
{
if(checkv6(IP))
return "IPv6";
return "Neither";
}
else
{
if(checkv4(IP))
{
return "IPv4";
}
return "Neither";
}
}
};