In this problem, your job to write a function to check whether a input string is a valid IPv4 address or IPv6 address or neither.
IPv4 addresses are canonically represented in dot-decimal notation, which consists of four decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1
;
Besides, you need to keep in mind that leading zeros in the IPv4 is illegal. For example, the address 172.16.254.01
is illegal.
IPv6 addresses are represented as eight groups of four hexadecimal digits, each group representing 16 bits. The groups are separated by colons (":"). For example, the address 2001:0db8:85a3:0000:0000:8a2e:0370:7334
is a legal one. Also, we could omit some leading zeros among four hexadecimal digits and some low-case characters in the address to upper-case ones, so 2001:db8:85a3:0:0:8A2E:0370:7334
is also a valid IPv6 address(Omit leading zeros and using upper cases).
However, we don't replace a consecutive group of zero value with a single empty group using two consecutive colons (::) to pursue simplicity. For example, 2001:0db8:85a3::8A2E:0370:7334
is an invalid IPv6 address.
Besides, you need to keep in mind that extra leading zeros in the IPv6 is also illegal. For example, the address 02001:0db8:85a3:0000:0000:8a2e:0370:7334
is also illegal.
Note: You could assume there is no extra space in the test cases and there may some special characters in the input string.
Example 1:
Input: "172.16.254.1" Output: "IPv4" Explanation: This is a valid IPv4 address, return "IPv4".
Example 2:
Input: "2001:0db8:85a3:0:0:8A2E:0370:7334" Output: "IPv6" Explanation: This is a valid IPv6 address, return "IPv6".
Example 3:
Input: "256.256.256.256" Output: "Neither" Explanation: This is neither a IPv4 address nor a IPv6 address.
這道題讓我們驗證兩種IP地址,LeetCode之前有一道關於IPv4的題Restore IP Addresses,給我們了一個字符串,讓我們通過在中間加點來找出所有正確的IP地址,這道題給了我們中間加點或者冒號的字符串,讓我們驗證其是否是正確的IPv4或者IPv6,感覺要稍稍復雜一些。那么我們只有分別來驗證了,那么我們怎么樣能快速的區別是IPv4或者IPv6呢,當然是通過中間的點或者冒號啦,所以我們首先在字符串中找冒號(當然你想找點也可以),如果字符串中沒有冒號,那么我們來驗證其是否是IPv4,如果有冒號,我們就來驗證其是否是IPv6.
首先對於IPv4,我們使用getline函數來截取兩個點之間的字符串,我們還需要一個計數器cnt來記錄我們已經截取了多少段,如果cnt大於4了,說明超過了4段,說明是不是正確的地址。如果取出的字符串為空,說明兩個點連在一起了,也不對。再有就是如果字符串長度大於1,且第一個字符是0,也不對。由於IPv4的地址在0到255之間,所以如果字符串長度大於3,也不正確。下面我們檢查每一個字符,如果有不是數字的字符,返回Neither。最后我們再把字符串轉為數字,如果不在0到255之間就是非法的。最后的最后,我們要保證cnt正好為4,而且最后一個字符不能是點,統統滿足以上條件才是正確的IPv4地址。
然后對於IPv6,我們也使用getline函數來截取兩個冒號之間的字符串,我們同樣需要計數器cnt來記錄我們已經截取了多少段,如果cnt大於8了,說明超過了8段,說明是不是正確的地址。如果取出的字符串為空,說明兩個冒號連在一起了,也不對。面我們檢查每一個字符,正確的字符應該是0到9之間的數字,或者a到f,或A到F之間的字符,如果出現了其他字符,返回Neither。最后的最后,我們要保證cnt正好為8,而且最后一個字符不能是冒號,統統滿足以上條件才是正確的IPv6地址。
class Solution { public: string validIPAddress(string IP) { istringstream is(IP); string t = ""; int cnt = 0; if (IP.find(':') == string::npos) { // Check IPv4 while (getline(is, t, '.')) { ++cnt; if (cnt > 4 || t.empty() || (t.size() > 1 && t[0] == '0') || t.size() > 3) return "Neither"; for (char c : t) { if (c < '0' || c > '9') return "Neither"; } int val = stoi(t); if (val < 0 || val > 255) return "Neither"; } return (cnt == 4 && IP.back() != '.') ? "IPv4" : "Neither"; } else { // Check IPv6 while (getline(is, t, ':')) { ++cnt; if (cnt > 8 || t.empty() || t.size() > 4) return "Neither"; for (char c : t) { if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return "Neither"; } } return (cnt == 8 && IP.back() != ':') ? "IPv6" : "Neither"; } } };
類似題目:
參考資料:
https://discuss.leetcode.com/topic/71572/java-solution
https://discuss.leetcode.com/topic/71418/short-regexp-solution/5