判断IPv4和IPv6的思路很相似,中间细节有稍许区别。
另外这里的测试用例不全,有些情判断不到,比如'192.168.0.1.',这中最后有多余字符的情况。

class Solution {
public:
    /**
     * 验证IP地址
     * @param IP string字符串 一个IP地址字符串
     * @return string字符串
     */
    bool IsValidIPv4(string &IP)
    {
        int len = IP.size(), i=0, start=0, cnt=0;
        while(i<len)
        {
            int tmp = 0;
            while(i<len && IP[i]!='.')
            {
                if('0'<=IP[i] && IP[i]<='9')
                {
                    tmp = tmp*10 + IP[i]-'0';
                    ++i;
                    if(i-start > 3) return false; //当前已非法,不必再继续计算了,同时防止过大的数导致tmp溢出
                }
                else
                {
                    return false; //中间有非法字符
                }
            }
            if((tmp<0 || tmp>255) || 
                (i-start>1 && IP[start]=='0') || 
                (i-start==0)) return false; //数值合法||起始位是0||'..'连续的点中间每数字
            ++cnt;
            start = (++i);
            if(cnt==4 && i<=len) return false; //结尾u有多余字符
        }
        return cnt==4;
    }
    bool IsValidIPv6(string &IP)
    {
        int len = IP.size(), i=0, start=0, cnt=0;
        while(i<len)
        {
            while(i<len && IP[i]!=':')
            {
                if(('0'<=IP[i] && IP[i]<='9') || 
                    ('a'<=IP[i] && IP[i]<='f') ||
                    ('A'<=IP[i] && IP[i]<='F'))
                {
                    ++i;
                    if(i-start > 4) return false; //当前已非法,不必再继续计算了
                }
                else
                {
                    return false; //中间有非法字符
                }
            }
            if(i-start==0 || i-start>4) return false; //两个':'之间合法字符太少或太多
            ++cnt;
            start = (++i);
            if(cnt==8 && i<=len) return false; //结尾有多余字符
        }
        return cnt==8;
    }
    string solve(string IP) {
        string ans = "Neither";
        int len=IP.size(), i=0;
        while(i<len && (IP[i]!='.' && IP[i]!=':')) ++i; //先确定可能v4还是v6
        if(i==len || len<7) return ans; //没找到'./:'或长度小于IPv4地址最小长度
        bool is_v4 = (IP[i] =='.');
        if(is_v4 && IsValidIPv4(IP)) ans = "IPv4";
        else if(IsValidIPv6(IP)) ans = "IPv6";
        return ans;
    }
};