牛客网的测试用例很水,程序错了都能通过9个。 (IPv4、IPv6没有分隔符连续的用例、IPv4没有前导“0”的用例)
我的split()函数写得稀烂,根据用例调试很久。模板的split()写得好一些。?
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 验证IP地址
* @param IP string字符串 一个IP地址字符串
* @return string字符串
*/
vector<string> split(string str, char c) {
vector<string> ans;
int start = -1;
int end = 0;
while (end < str.size()) {
if (str[end] == c) { //粗心,不是end == c
if(end == str.size() - 1){
ans.push_back(str.substr(start + 1, end - start));
ans.push_back("");
start = end;
}
ans.push_back(str.substr(start + 1, end - start - 1)); //"1"是1组,“1.1..1”是4组,“.1.1.1”是4组,“1.1.1.1.”是4组
start = end;
}
else if (end == str.size() - 1) { //调试很久,不然最后一组不能放入
ans.push_back(str.substr(start + 1, end - start));
start = end;
}
end++;
}
return ans;
}
bool isIPv4(string IP) {
vector<string> ip = split(IP, '.');
//必须有4组
if (ip.size() != 4)
return false;
//每组进行分析
for (int i = 0; i < 4; i++) {
//每组不为空,且最多有3个字符
if (ip[i].size() == 0 || ip[i].size() > 3)
return false;
//不能有前导“0”
if(ip[i].size()>1 && ip[i][0] == '0')
return false;
//必须是十进制字符
for (int j = 0; j < ip[i].size(); j++)
if (!((ip[i][j] >= '0' && ip[i][j] <= '9')))
return false;
//必须在0-255范围
int num = stoi(ip[i]); //调试,ip[i]必须是数字,必须【非空】。
if (num > 255)
return false;
}
return true;
}
bool isIPv6(string IP) {
vector<string> ip = split(IP, ':');
//必须有8组
if (ip.size() != 8)
return false;
//每组进行分析
for (int i = 0; i < 8; i++) {
//每组不为空,且最多有4个字符
if (ip[i].size() == 0 || ip[i].size() > 4)
return false;
//必须是十六进制字符
for (int j = 0; j < ip[i].size(); j++)
if (!((ip[i][j] >= '0' && ip[i][j] <= '9') ||
(ip[i][j] >= 'a' && ip[i][j] <= 'f') ||
(ip[i][j] >= 'A' && ip[i][j] <= 'F'))){ //粗心,忘记加等号“=”。
cout<<ip[i][j]<<endl;;
return false;
}
}
return true;
}
string solve(string IP) {
// write code here
bool flag1 = isIPv4(IP);
bool flag2 = isIPv6(IP);
if (flag1)
return "IPv4";
if (flag2)
return "IPv6";
return "Neither";
}
};
?模板的split(),在while循环中,会把截取的字符串去掉,所以每次只需要截取前n个即可。
vector<string> split(string str, char c) {
vector<string> ans;
int end;
while((end = str.find(c)) && end != str.npos){
ans.push_back(str.substr(0,end));
str = str.substr(end+1);
}
ans.push_back(str); //易粗心漏掉
return ans;
}
一些关键点:
C++中std::string::npos的用法_C 语言_脚本之家 (jb51.net)
?C语言中,while()语句括号内可以是赋值语句吗? (sogou.com)
此外,刷到i++和++i的区别: