0468. 验证IP地址 Validate IP Address
这个是处理字符串的问题.
步骤大致如下:
- 先检查是不是 ipv4, 如果是, 直接返回
- 先以
.
将字符串分隔成多个部分, parts - parts 数组的长度应该是 4
- 检查每一部分字符串
- 长度在 [1..3] 之间
- 如果以
0
为前缀的话, 只能包含0
- 检查里面的字符, 只能包含
0-9
这10 个字符, 可以用std::isdigit(c)
- 将它转换成整数, 数值范围是 [0..255]
- 先以
- 再检查是不是 ipv6, 如果是, 就返回
- 以
:
将字符串分隔成多个部分, parts - parts 数组的长度是 8
- 检查每一部分字符串
- 字符串长度是 [1..4] 之间
- 检查里面的字符, 只能包含 0-9, a-f, A-F这些字符, 可以用
std::is_xdigit(c)
- 不需要把它再转换成整数
- 以
- 返回
Neither
以下是代码实现:
Rust
#![allow(unused)] fn main() { fn is_ipv4(query: &str) -> bool { // 用 `.` 来分隔各部分 // 并判断每个部分是有效的数值 // 数值不带有前缀0 let parts: Vec<&str> = query.split('.').collect(); if parts.len() != 4 { return false; } for part in parts { if part.is_empty() || part.len() > 3 { return false; } // 数值不带有前缀0 if part.len() > 1 && part.starts_with("0") { return false; } // 判断字符的范围, 0-9 for c in part.chars() { if !c.is_ascii_digit() { return false; } } if let Ok(val) = part.parse::<i32>() { // 数值范围是 0..255 if !(0..=255).contains(&val) { return false; } } else { // 不是有效的整数 return false; } } true } fn is_ipv6(query: &str) -> bool { // 使用 `:` 作为分隔符 // 每个部分是16进制的整数, 16进制支持大小写, 最多包含4个字符 // 可以有0作为前缀 // 不需要考虑缩写 let parts: Vec<&str> = query.split(':').collect(); if parts.len() != 8 { return false; } for part in parts { // 1-4个字符 if part.is_empty() || part.len() > 4 { return false; } for c in part.chars() { // 判断字符的范围, 0-9, a-f, A-F if !c.is_ascii_hexdigit() { return false; } } } true } pub fn valid_ip_address1(query_ip: String) -> String { if is_ipv4(&query_ip) { "IPv4".to_owned() } else if is_ipv6(&query_ip) { "IPv6".to_owned() } else { "Neither".to_owned() } } }
C++
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <sstream>
class Solution {
public:
static bool isIPv4(const std::string& query) {
// 用 `.` 来分隔各部分
// 并判断每个部分是有效的数值
// 数值不带有前缀0
if (query.empty() || query[0] == '.' || query[query.size() - 1] == '.') {
return false;
}
int part_count = 0;
std::stringstream ss(query);
std::string part;
while (std::getline(ss, part, '.')) {
// 数值不带有前缀0
if (part[0] == '0' && part.size() > 1) {
return false;
}
if (part.size() < 1 || part.size() > 3) {
return false;
}
// 判断字符的范围, 0-9
for (char c : part) {
if (!std::isdigit(c)) {
return false;
}
}
size_t pos = 0;
const int val = std::stoi(part, &pos);
// 不是有效的整数
if (pos != part.size()) {
//return false;
}
// 数值范围是 0..255
if (val < 0 || val > 255) {
return false;
}
part_count += 1;
}
// 要有4个部分
return part_count == 4;
}
static bool isIPv6(const std::string& query) {
// 使用 `:` 作为分隔符
// 每个部分是16进制的整数, 16进制支持大小写, 最多包含4个字符
// 可以有0作为前缀
// 不需要考虑缩写
if (query.empty() || query[0] == ':' || query[query.size() - 1] == ':') {
return false;
}
int part_count = 0;
std::stringstream ss(query);
std::string part;
while (std::getline(ss, part, ':')) {
// 1-4个字符
if (part.size() < 1 || part.size() > 4) {
return false;
}
for (char c : part) {
// 判断字符的范围, 0-9, a-f, A-F
if (!std::isxdigit(c)) {
return false;
}
}
part_count += 1;
}
return part_count == 8;
}
static std::string validIPAddress(std::string queryIP) {
if (isIPv4(queryIP)) {
return "IPv4";
}
if (isIPv6(queryIP)) {
return "IPv6";
}
return "Neither";
}
};