1. 程式人生 > >[LeetCode] Validate IP Address 驗證IP地址

[LeetCode] Validate IP Address 驗證IP地址

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";
        }
    }
};

類似題目:

參考資料: