Skip to content

Commit

Permalink
leetcode: Add 0468
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Sep 24, 2024
1 parent 78a5ff8 commit 06a0764
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@
- [0374. 猜数字大小 Guess Number Higher or Lower](leetcode/0374.guess-number-higher-or-lower/index.md)
- [0394. 字符串解码 Decode String](leetcode/0394.decode-string/index.md)
- [0401-0500](leetcode/by-id/0401-0500.md)
- [0468. 验证IP地址 Validate IP Address](leetcode/0468.validate-ip-address/index.md)
- [0485. 最大连续1的个数 Max Consecutive Ones](leetcode/0485.max-consecutive-ones/index.md)
- [0496. 下一个更大元素 I Next Greater Element I](leetcode/0496.next-greater-element-i/index.md)
- [0501-0600](leetcode/by-id/0501-0600.md)
Expand Down
1 change: 1 addition & 0 deletions src/leetcode/0468.validate-ip-address/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/main
7 changes: 7 additions & 0 deletions src/leetcode/0468.validate-ip-address/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "lc-0468-validate-ip-address"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
3 changes: 3 additions & 0 deletions src/leetcode/0468.validate-ip-address/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

build: main.cpp
g++ -g main.cpp -o main
31 changes: 31 additions & 0 deletions src/leetcode/0468.validate-ip-address/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 0468. 验证IP地址 Validate IP Address

[问题描述](https://leetcode.com/problems/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

```rust
{{#include src/main.rs:5:82}}
```
116 changes: 116 additions & 0 deletions src/leetcode/0468.validate-ip-address/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright (c) 2024 Xu Shaohua <[email protected]>. All rights reserved.
// Use of this source is governed by General Public License that can be found
// in the LICENSE file.

#include <cassert>

#include <iostream>
#include <sstream>
#include <string>

class Solution {
public:
static bool isIPv4(const std::string& query) {
// 用 `.` 来分隔各部分
// 并判断每个部分是有效的数值
// 数值不带有前缀0

if (query[0] == '.' || query[query.size() - 1] == '.') {
return false;
}
std::stringstream ss(query);
std::string part;
int part_count = 0;
while (std::getline(ss, part, '.')) {
part_count += 1;
// 数值不带有前缀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;
}
}

const int val = std::stoi(part);
// 不是有效的整数
if (val == 0 && part != "0") {
return false;
}
// 数值范围是 0..255
if (val < 0 || val > 255) {
return false;
}
}

// 要有4个部分
return part_count == 4;
}

static bool isIPv6(const std::string& query) {
// 使用 `:` 作为分隔符
// 每个部分是16进制的整数, 16进制支持大小写, 最多包含4个字符
// 可以有0作为前缀
// 不需要考虑缩写

if (query[0] == ':' || query[query.size() - 1] == ':') {
return false;
}

std::stringstream ss(query);
std::string part;
int part_count = 0;
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";
}
};

void checkSolution() {
{
const std::string s1 = "2001:0db8:85a3:0:0:8A2E:0370:7334:";
const std::string expected = "Neither";
const std::string out = Solution::validIPAddress(s1);
assert(out == expected);
}

{
const std::string s1 = "1e1.4.5.6";
const std::string expected = "Neither";
const std::string out = Solution::validIPAddress(s1);
assert(out == expected);
}
}

int main() {
checkSolution();
return 0;
}
114 changes: 114 additions & 0 deletions src/leetcode/0468.validate-ip-address/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) 2024 Xu Shaohua <[email protected]>. All rights reserved.
// Use of this source is governed by General Public License that can be found
// in the LICENSE file.

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.len() < 1 || 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 val < 0 || val > 255 {
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.len() < 1 || 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()
}
}

pub type SolutionFn = fn(String) -> String;

fn check_solution(func: SolutionFn) {
{
let s1 = "2001:0db8:85a3:0:0:8A2E:0370:7334:".to_owned();
let expected = "Neither";
let out = func(s1);
assert_eq!(out, expected);
}

{
let s1 = "1e1.4.5.6".to_owned();
let expected = "Neither";
let out = func(s1);
assert_eq!(out, expected);
}
}

fn main() {
check_solution(valid_ip_address1);
}

#[cfg(test)]
mod tests {
use super::{check_solution, valid_ip_address1};

#[test]
fn test_valid_ip_address1() {
check_solution(valid_ip_address1);
}
}
14 changes: 9 additions & 5 deletions src/leetcode/tags/string/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@

## 中级

- [6. Z 字形变换](https://leetcode.com/problems/zigzag-conversion)
- [8. 字符串转换整数(atoi)](https://leetcode.com/problems/string-to-integer-atoi)
- [17.电话号码的字母组合](https://leetcode.com/problems/letter-combinations-of-a-phone-number)
- [165.比较版本号](https://leetcode.com/problems/compare-version-numbers)
- [2414. Length of the Longest Alphabetical Continuous Substring](https://leetcode.com/problems/length-of-the-longest-alphabetical-continuous-substring/description/)
1. [0468. 验证IP地址 Validate IP Address](../../0468.validate-ip-address/index.md)

TODO:

- [0006. Z 字形变换](https://leetcode.com/problems/zigzag-conversion)
- [0008. 字符串转换整数(atoi)](https://leetcode.com/problems/string-to-integer-atoi)
- [0017.电话号码的字母组合](https://leetcode.com/problems/letter-combinations-of-a-phone-number)
- [0165.比较版本号](https://leetcode.com/problems/compare-version-numbers)
- [2414. Length of the Longest Alphabetical Continuous Substring](https://leetcode.com/problems/length-of-the-longest-alphabetical-continuous-substring/description/)

0 comments on commit 06a0764

Please sign in to comment.