微软面试题: LeetCode 468 验证IP地址 出现次数:3
本题是一道细节题,很烦人,但是却频繁出现在 微软等大公司的面试中。
主要考察面试者是否具有良好的代码风格和代码调试能力。
这里使用了 stringstream + getline 分割字符串,使用 atoi将字符串转成整数。
主要的坑也来自这两块。
坑1 : atoi("1e1") 返回的结果 是1 不是 0。手动实现 atoi 也是微软的高频面试题。
坑2 : 使用 stringstream + getline 分割字符串 ".192.1.102.32." ==> {"192","1","102","32"}
具体见下面代码和注释:
1 class Solution { 2 public: 3 string validIPAddress(string IP) { 4 // if(IP.empty()) return "Neither"; 5 int n = IP.size() ; 6 //因为 下面的 split 函数会把 ".192.1.102.43." 转成 {"192","1","102","32"} 7 //所以 首尾字符是分隔符的 在此 直接判不合法 8 if(n > 0 &&(IP[0] == '.'||IP[0] == ':'||IP[n-1] == '.'||IP[n-1] == ':')) return "Neither"; 9 10 string::size_type position1,position2; 11 position1 = IP.find("."); 12 position2 = IP.find(":"); 13 vector<string> ret; 14 //有分割符'.' 没有 ':' 只有可能是IPV4 15 if(position1 != IP.npos && position2 == IP.npos) 16 { 17 //按分割符 '.' 分割 IP 18 ret = split(IP,'.'); 19 //分割后 判断IP是否是一个合法的IPV4 地址 20 return validIPAddressHelper(ret,1); 21 } 22 //有分割符':' 没有 '.' 只有可能是IPV6 23 else if(position2 != IP.npos && position1 == IP.npos) 24 { 25 //按分割符 ':' 分割 IP 26 ret = split(IP,':'); 27 //分割后 判断IP是否是一个合法的IPV4 地址 28 return validIPAddressHelper(ret,2); 29 } 30 //非法IP 地址 31 else{ 32 return "Neither"; 33 } 34 } 35 36 //使用 stringstream + getline 分割字符串 37 //"192.1.102.32." ==> {"192","1","102","32"} 38 vector<string> split(string str,char del) 39 { 40 stringstream ss(str); 41 string tok; 42 bool flag=true; 43 vector<string> ret; 44 while(getline(ss,tok,del)) 45 { 46 ret.push_back(tok); 47 } 48 return ret; 49 } 50 51 string validIPAddressHelper(vector<string> &ret,int flag) 52 { 53 if(flag == 1)//IPV4 54 { 55 if(ret.size() != 4) return "Neither"; 56 for(auto &str : ret) 57 { 58 int num = atoi(str.c_str());//atoi 函数 59 if(num == 0) 60 { 61 if(str.size() == 0) return "Neither"; 62 //分割得到的不是数字字符,不合法 63 for(char &c:str) 64 { 65 if(!isdigit(c)) 66 { 67 return "Neither"; 68 } 69 } 70 } 71 else 72 { 73 if(str[0] == '0' && str != "0") return "Neither"; 74 if(num < 0 || num > 255) return "Neither"; 75 } 76 } 77 return "IPv4"; 78 } 79 if(flag == 2)//IPV6 80 { 81 if(ret.size() != 8 ) return "Neither"; 82 for(auto &str : ret) 83 { 84 if(str.size() > 4 || str.size() == 0 ) return "Neither"; 85 for(char &c:str) 86 { 87 if(!(isdigit(c) || (isalpha(c) && 'A' <= toupper(c) && toupper(c) < 'G'))) 88 { 89 return "Neither"; 90 } 91 } 92 } 93 return "IPv6"; 94 } 95 //函数调用错误 96 return "FLAG ERROR"; 97 } 98 99 };