题解 | #合法IP#
合法IP
http://www.nowcoder.com/practice/995b8a548827494699dc38c3e2a54ee9
吐槽
题目的条件其实挺模糊的,也是走了测试用例才发现还有那么多的条件
划分
- 其实字符串分割和判断,最重要的是细心。如何划分字符串的属性来做判断,应该是比较重要的。
- 首先,可以得知分割符是
.
,那么我们就按照分隔符的方式,划分子字符串存储到一个列表中,这样问题就变成了判断每个子字符串的字段是否合法。前提是,字段满足4个,且只有四个。 - 其次,依次判断子字符串中是否字符合法,范围合法。
- 字符合法,所有字符必须为阿拉伯字符,测试用例中出现过
+
符号的 - 在出现两个字符以上的,需要判断第一位是否为
0
, 因为01,08,012
这类的是不合法的 - 由于之前已经判断了所有的都是阿拉伯,那么可以直接转换为数值来判断范围是否在
0~255
之间
代码
class IP
{
public:
IP() {}
IP(std::string& str);
bool is_valid() const;
private:
std::vector<std::string> _sub_ip;
};
// description: 划分子串,然后存储下来
IP::IP(std::string& _str)
{
while (!_str.empty())
{
int pos = _str.find('.');
if (pos == std::string::npos)
{// 如果没有找到
_sub_ip.push_back(_str);
_str.erase(0, _str.length());
}
else
{// 如果找到 .
_sub_ip.push_back(_str.substr(0, pos));
_str.erase(0, pos + 1);
}
}
}
bool IP::is_valid() const
{
if (_sub_ip.size() != 4)
{// 四个字段不能多,不能少
return false;
}
for (const auto& sub : _sub_ip)
{// 遍历所有子段,判断是否合法
if (sub.length() < 1 || sub.length() > 3)
{// 判断子段的长度都在 1 ~ 3 之间
return false;
}
else
{// 满足子段的长度都在 1 ~ 3 之间,判断字符是否合法
for (int i = 0; i < sub.length(); ++i)
{
if (sub[i] < '0' || sub[i] > '9')
{// 字符是否满足在 0 ~ 9
return false;
}
if (sub.length() > 1 && sub[0] == '0')
{// 判断 01,02之类的
return false;
}
if (i == sub.length() - 1)
{// 判断是否数值在范围内
int sub_value = atoi(sub.c_str());
if (sub_value < 0 || sub_value > 255)
return false;
}
}
}
}
return true;
}
main函数内容
int main()
{
std::string str;
while (std::cin >> str)
{
IP ip(str);
std::cout << (ip.is_valid() ? "YES" : "NO") << std::endl;
}
return 0;
}