ipv4地址:1.必须是四个非空子串
2.每个非空子串不含前导零
3.子串里字符只能是0~255
ipv6地址:1.必须是八个非空子串
2。每段非空串得长度是否在1~4之间,且不含0-9,a-f,A-F之外得字符。
3.同时0-9也不允许含前导零
class Solution {
public:
string validIPAddress(string queryIP) {
vector<string> ipv4;
vector<string> ipv6;
char v4='.';
char v6=':';
if(queryIP.size()==0) return "Neither";
char c=queryIP[queryIP.size()-1];
if(c==v4||c==v6) return "Neither";//如果地址字符串末尾是:or. 那肯定不是
split(queryIP,ipv4,v4);
split(queryIP,ipv6,v6);
if(IsIPv4(ipv4)) return "IPv4";
IsIPv6(ipv6);
if(IsIPv6(ipv6)) return "IPv6";
return "Neither";
}
private:
bool IsIPv4(vector<string> &ip)
{
if(ip.size()!=4) return false;
for(auto subip:ip)
{
if(subip[0]=='0'&&subip.size()>1||subip.size()>3||subip.empty()) return false;
//一定要判空subip.empty()不然底下stoi会报错
for(char c:subip)
{
if(c<'0'||c>'9') return false;//先判断每个是不是数字
}
int subipint=stoi(subip);
if(subipint<0||subipint>255) return false;//再判断数字的范围
}
return true;
}
bool IsIPv6(vector<string> &ip)
{
if(ip.size()!=8) return false;//首先是不是八个子串
for(auto subip:ip)
{
int len=subip.size();
if(len<=0||len>=5) return false;//八个子串的长度是不是1~4
for(int i=0;i<subip.size();i++)
{
if(subip[i]<='f'&&subip[i]>='a'||subip[i]<='F'&&subip[i]>='A'||subip[i]<='9'&&subip[i]>='0') continue;
else return false;
// if(subip[i]<'0'||subip[i]>'9'&&subip[i]<'A'||subip[i]>'F'&&subip[i]<'a'||subip[i]>'f') return false;
}
}
return true;
}
void split(string s,vector<string>&ip,char c)
{
// int flag=0,len=s.size();
// if(s[len-1]==c) flag=1;//如果ip地址的最末尾是'.'或者是":",那肯定就不是ip地址
s+=c;
for(int i=0;i<s.size();i++)
{
int j=i;
string item;
while(s[j]!=c) item+=s[j++];
i=j;
ip.push_back(item);
}
}
};
答案 但是内存消耗不容乐观
其中出现的几个问题总结一一下,第一个是spilt函数截取字符串的问题。
ipv4:1.子字符串为4个,2.子字符串不为空,子字符串的长度不能大于3(即数字在1-3个之间),子字符串不含前导零 3.子字符串的每个字符必须是数字,4.子字符串在0~255之间(先使用stoi()转为int)
ipv6:1.子字符串为8个 2.子字符串的长度必须要在1-4之间(不能<1不能>5) 3.子字符串的字符必须在0-9,a-f,A-F之间