概述
首先题目链接如下
Leetcode 468-验证IP地址
牛客 NC113-验证IP地址
题目要求如下:
思路:
(1)首先IPv4和IPv6的判断要分为两个不同的函数,根据传入string中.
、:
的数量决定传入哪个函数,还是直接返回"Neither"
代码如下:
vector<string> res_token;//全局变量
string validIPAddress(string IP) {
if(count(IP.begin(),IP.end(),'.')==3)
return v4Solve(IP);
else if(count(IP.begin(),IP.end(),':')==7)
return v6Solve(IP);
else return "Neither";
}
(2)不论是IPv4还是IPv6的验证子函数,都需要将传入的string按分隔符.
或:
分为几个token,然后依次判断某个token是否合法,这里就需要用到了split,实现的思路详见之前的博客,链接如下:
用C++实现split分割字符串
⚠️注意:上面的博客也提到了,由于可能有连续的分隔符,因此token可能为空因此需要判断,否则会访问越界导致段错误
代码如下:
void split(string s,char ch){
string token;
istringstream str_stream(s);
while(getline(str_stream,token,ch))
res_token.push_back(token);
}
(3)IPv4的验证思路如下:
①首先验证每个token的长度是否符合,如果为空或超过3位,直接返回"Neither"
②要求不能有多余的0,因此对于每个token,若长度大于1且第1位(下标为0)是0,则不合法,返回"Neither"
③长度符合的情况下,计算每个token的大小,若出现了非数字、或计算结果不在[0,255]范围内,返回"Neither",为了看起来更干净加单独的一个子函数calc()
④若上边的关卡都通过了,说明是一个正确的IPv4地址,返回"IPv4"
代码如下:
string v4Solve(string s){
split(s,'.');
if(res_token.size()!=4)
return "Neither";
for(int i=0;i<res_token.size();i++){
if(res_token[i].size()==0 || res_token[i].size()>3)
return "Neither";
if(res_token[i].size()>1 && res_token[i][0]=='0')
return "Neither";
if(calc(res_token[i])<0 || calc(res_token[i])>255)
return "Neither";
}
return "IPv4";
}
子函数calc()
如下:
int calc(string s){
int sum=0;
for(int i=0;i<s.size();i++){
if(s[i]>'9' || s[i]<'0')
return -1;
sum=sum*10+s[i]-'0';
}
return sum;
}
(4)IPv6的验证思路如下:
①同样,先验证每个token的长度是否符合,如果为空或超过4位,直接返回"Neither"
②对于每个token,验证每一位是否属于数字、小写字母或大写字母,若都不属于则不是IPv6地址,返回"Neither",为了看起来更干净加单独的一个子函数isValid()
③若上边的关卡都通过了,说明是一个正确的IPv6地址,返回"IPv6"
代码如下:
string v6Solve(string s){
split(s,':');
if(res_token.size()!=8)
return "Neither";
for(int i=0;i<res_token.size();i++){
if(res_token[i].size()==0 || res_token[i].size()>4)
return "Neither";
if(!isValid(res_token[i]))
return "Neither";
}
return "IPv6";
}
子函数isValid()
如下:
bool isValid(string s){
for(int i=0;i<s.size();i++){
if((s[i]>='0' && s[i]<='9')||(s[i]>='a' && s[i]<='f')||(s[i]>='A' && s[i]<='F'))
continue;
else return false;
}
return true;
}
可能你注意到了一开始验证了token的数量,这是因为对于"192.1.1."
这种字符串,虽然也是3个分隔符,但token只有3个,实验如下:
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
int main(){
string s="192.1.1.";
string token;
istringstream str_input(s);
vector<string> res;
while(getline(str_input,token,'.'))
res.push_back(token);
for(auto it:res)
cout<<it<<", size is "<<it.size()<<endl;
}
输出如下:
wangkailin@wangkailindeMacBook-Pro ~ % cd "/Users/wangkailin/Desktop/" && g++
192, size is 3
1, size is 1
1, size is 1
因为getline遇到最后一个分隔符后同时也读完了,因此只有3个token,所以需要额外判断一下token的数量。
然后看一下Python的split情况:
IP="192.1.1."
tokens=IP.split('.')
for x in tokens:
print(len(x))
运行结果如下:
python3 -u "/Users/wangkailin/Desktop/split.py"
wangkailin@wangkailindeMacBook-Pro ~ % python3 -u "/Users/wangkailin/Desktop/split.py"
3
1
1
0
这种情况就不用单独判断token的数量了,但是C++它快啊
运行结果如下:
最后
以上就是彩色大白为你收集整理的验证 IPv4 / IPv6 地址(C++) -Leetcode 468的全部内容,希望文章能够帮你解决验证 IPv4 / IPv6 地址(C++) -Leetcode 468所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复