公司 IT 防攻擊小組在做一次專項分析,由於受到干擾,本應接收到的一組 ip 地址(IPv4)信息被合並成一條長信息且缺失了部分內容。
為了判斷缺失情況,請你幫忙解析出字符串 str 形式的長信息中所有合法 ip 地址的個數,解析出的相同地址需要進行去重。
字符串長度 <= 100000,字符串由數字(’0’ - ‘9’)以及 ‘.’ 組成,假設 IPv4 合法地址的規則如下:
(1) 采用 "." 分隔成四個字段,每個字段采用十進制記錄。
(2) 每個字段的值范圍為:[0,255]。
(3) 每個字段的值除了 0 外,其他情況首位不可為 0。如:0.0.0.0 合法,0.01.0.1 不合法。
例1:
輸入:str = "1.1.1111.16..172.16.254.1.1"
輸出:5
解釋:字符串 str 可能被分為:"172.16.254.1", "72.16.254.1", "2.16.254.1", "16.254.1.1", "6.254.1.1"
例2:
輸入:str = "1.2.3.04"
輸出:1
解釋:字符串 str 只可能被分為 "1.2.3.0"
參考:
#include <iostream> #include <string> #include <regex> #include <list> #include <set> using namespace std; bool IsValidIp(string ipAddr) { string regStr = "^((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|[1-9])"\ "(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3})|(0.0.0.0)$"; regex regIp(regStr); bool matchValue = regex_match(ipAddr, regIp); return matchValue; } int main() { string inPutStr = "1.2.3.04"; // Step 1:找到所有.的位置 vector<int> vLocal; for (int strI = 0; strI < inPutStr.length() - 1; strI++) { if (inPutStr[strI] == '.') { vLocal.push_back(strI); } } /* 打印.位置信息 */ for (int debugI = 0; debugI < vLocal.size(); debugI++) { cout<<vLocal[debugI]<<","; } cout<<inPutStr.size()<<","<<inPutStr.length()<<","<<endl; set<string> ipSet; // Step 2:按照.的位置進行遍歷 for (vector<int>::iterator it = vLocal.begin(); it != vLocal.end(); it++) { cout<<"*it is "<<*it<<endl; // .的位置不合法,或者連續出現2個. if (((*(it + 2) - *(it + 1)) < 1) || ((*(it + 1) - *(it)) < 1) || (*(it + 2) == (inPutStr.length() - 1)) || (*(it) == 0)) { cout<<*it<<"is unvalid"<<endl; continue; } int left = *it - 1; // 左邊偏移1位 int right = *(it + 2) + 1; // 右邊第三個分隔符偏移1位 string ipAddrTemp = inPutStr.substr(left, (right - left + 1)); bool matchR = IsValidIp(ipAddrTemp); cout<<"[1]left is "<<left<<", right is "<<right<<", str is "<<ipAddrTemp<<", matchR is"<<matchR<<endl; // Step 3:如果是合法的地址,則根據合法地址進行前后探索 if (matchR) { for (int i = right; i <= (right + 2) && (i < inPutStr.size()); i++) { for (int j = left; (j >= (left - 2) && (j >= 0)); j--) { ipAddrTemp = inPutStr.substr(j, i - j + 1); matchR = IsValidIp(ipAddrTemp); cout<<"[2]left ="<<left<<", right ="<<right<<", str is "<<ipAddrTemp<<", matchR is"<<matchR<<endl; if (matchR) { ipSet.insert(ipAddrTemp); } } } } } for (set<string>::iterator itStr = ipSet.begin(); itStr != ipSet.end(); itStr++) { cout<<"Valid IpAddr "<<*itStr<<endl; } cout<<"Total IP is"<<ipSet.size()<<endl; return 0; }
看到別人的解答中,用到了正則表達式,這個還是挺巧妙的。關於正則表達式的基本使用,參考一下:https://www.zhihu.com/question/48219401/answer/742444326