我是靠谱客的博主 彩色大白,最近开发中收集的这篇文章主要介绍验证 IPv4 / IPv6 地址(C++) -Leetcode 468,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

首先题目链接如下
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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部