Skip to content

Commit 8a97a27

Browse files
committed
说明:
1. week 91 2. 调整结构, 清理不必要文件 3. 简单修复macro tree不能识别负数的bug 4. 升级rust版本 5. 去处所有unsafe代码 6. tree结构加debug方便定位问题
1 parent c9b0435 commit 8a97a27

31 files changed

+1048
-173
lines changed

.github/workflows/CICD.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
uses: actions/checkout@v2
2525
- name: Setup Rust
2626
run: |
27-
rustup toolchain add ${{ matrix.toolchain }} --component llvm-tools-preview
27+
rustup toolchain add ${{ matrix.toolchain }} --component llvm-tools
2828
rustup override set ${{ matrix.toolchain }}
2929
- name: Configure cache
3030
uses: actions/cache@v2
@@ -72,7 +72,7 @@ jobs:
7272
uses: actions/checkout@v2
7373
- name: Setup Rust
7474
run: |
75-
rustup toolchain add nightly --component llvm-tools-preview
75+
rustup toolchain add nightly --component llvm-tools
7676
rustup override set nightly
7777
cargo install grcov
7878
- name: Configure cache

.vscode/settings.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
"rust-analyzer.debug.engine": "vadimcn.vscode-lldb",
66
"rust-analyzer.debug.openDebugPane": true,
77
"rust-analyzer.inlayHints.typeHints.hideNamedConstructor": true,
8-
// "rust-analyzer.server.path": "~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rust-analyzer",
9-
"rust-analyzer.runnableEnv": {
10-
"RUST_BACKTRACE": "0"
11-
},
128
"coverage-gutters.coverageBaseDir": "target/coverage",
139
"coverage-gutters.coverageFileNames": [
1410
"lcov.info",

.vscode/tasks.json

Lines changed: 0 additions & 41 deletions
This file was deleted.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: clean coverage
1+
.PHONY: clean test coverage lint
22

33
clean:
44
@cargo clean

datastructure/src/tree.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,102 @@
11

22
use std::cell::RefCell;
3+
use std::fmt::{Display, Debug};
34
use std::rc::Rc;
45

5-
#[derive(Debug, PartialEq, Eq)]
6+
#[derive(Eq)]
67
pub struct TreeNode {
78
pub val: i32,
89
pub left: Option<Rc<RefCell<TreeNode>>>,
910
pub right: Option<Rc<RefCell<TreeNode>>>,
11+
}
12+
13+
impl PartialEq for TreeNode {
14+
fn eq(&self, other: &Self) -> bool {
15+
if self.val != other.val {
16+
return false;
17+
}
18+
19+
match (&self.left, &other.left) {
20+
(None, None) => {}
21+
(Some(_), None) => return false,
22+
(None, Some(_)) => return false,
23+
(Some(l), Some(r)) => {
24+
if !l.borrow().eq(&r.borrow()) {
25+
return false;
26+
}
27+
}
28+
}
29+
match (&self.right, &other.right) {
30+
(None, None) => {}
31+
(Some(_), None) => return false,
32+
(None, Some(_)) => return false,
33+
(Some(l), Some(r)) => {
34+
if !l.borrow().eq(&r.borrow()) {
35+
return false;
36+
}
37+
}
38+
}
39+
true
40+
}
41+
}
42+
43+
impl Display for TreeNode{
44+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45+
self.display(f, 0)
46+
}
47+
}
48+
49+
impl TreeNode{
50+
fn display(&self, f: &mut std::fmt::Formatter<'_>, depth: usize) -> std::fmt::Result {
51+
let mut ret = String::new();
52+
if depth > 0 {
53+
for _ in 0..depth-1 {
54+
ret.push_str("│ ");
55+
}
56+
ret.push_str("├─ ");
57+
}
58+
ret.push_str(&self.val.to_string());
59+
ret.push_str("\n");
60+
write!(f, "{}", ret)?;
61+
if let Some(left) = &self.left {
62+
left.borrow().display(f, depth+1)?;
63+
}
64+
if let Some(right) = &self.right {
65+
right.borrow().display(f, depth+1)?;
66+
}
67+
Ok(())
68+
}
69+
}
70+
71+
impl Debug for TreeNode {
72+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73+
self.display(f, 0)
74+
}
75+
}
76+
77+
#[cfg(test)]
78+
mod test{
79+
use super::*;
80+
81+
#[test]
82+
fn test_tree_display(){
83+
let root = Rc::new(RefCell::new(TreeNode{
84+
val: 1,
85+
left: Some(Rc::new(RefCell::new(TreeNode{
86+
val: 2,
87+
left: Some(Rc::new(RefCell::new(TreeNode{
88+
val: 4,
89+
left: None,
90+
right: None,
91+
}))),
92+
right: None,
93+
}))),
94+
right: Some(Rc::new(RefCell::new(TreeNode{
95+
val: 3,
96+
left: None,
97+
right: None,
98+
}))),
99+
}));
100+
println!("{}", root.borrow());
101+
}
10102
}

macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! 树/链表题, 除了题目自身难受, 构建测试用例也是难事
22
//! `Rc` `RefCell` `Box` 反复写, 人都麻了.
33
//!
4-
//! 所以正这个 proc_macro, 自己定义一套 dsl, 至少方便一下测试用例.
4+
//! 所以整这个 proc_macro, 自己定义一套 dsl, 至少方便一下测试用例.
55
//!
66
use proc_macro::TokenStream;
77

macros/src/tree_impl.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl From<TokenStream> for TreeNode {
6666
fn from(stream: TokenStream) -> Self {
6767
let mut tree_node = TreeNode::default();
6868
let mut which_node = WhichNode::S;
69+
let mut negtive = false;
6970

7071
for tree in stream.into_iter() {
7172
match tree {
@@ -88,10 +89,19 @@ impl From<TokenStream> for TreeNode {
8889
which_node = WhichNode::R;
8990
}
9091
}
91-
TokenTree::Punct(_punct) => {}
92+
TokenTree::Punct(_punct) => {
93+
if _punct.to_string().eq("-") {
94+
negtive = true;
95+
}
96+
}
9297
TokenTree::Literal(literal) => {
9398
let lit = literal.to_string().parse().unwrap();
94-
tree_node.val = lit;
99+
if negtive {
100+
tree_node.val = 0-lit;
101+
negtive = false;
102+
} else {
103+
tree_node.val = lit;
104+
}
95105
}
96106
}
97107
}
@@ -104,7 +114,7 @@ mod test {
104114
use super::*;
105115
#[test]
106116
fn test_x() {
107-
let ts = TokenStream::from_str("{1, right:{2, left: {3}}}").unwrap();
117+
let ts = TokenStream::from_str("{1, right:{2, left: {-3}}}").unwrap();
108118
let tree = tree(ts);
109119
dbg!(tree);
110120
}

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
22
channel = "nightly"
3-
components = [ "llvm-tools-preview", "rust-analyzer"]
3+
components = [ "llvm-tools", ]

src/array/ext.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
pub mod rotate;
1+
//! 数组相关的扩展算法
2+
//!
3+
//! 1. 旋转数组 [rotate]
4+
//! 2. 随机算法 [random]
5+
//! 3. 快速排序 [quick]
6+
//! 4. KMP算法 [kmp]
7+
//! 5. 数学相关 [math]
8+
//! 6. 拓扑排序 [topological]
9+
//! 7. 字典树 [trie]
10+
//! 8. 并查集 [disjoint]
11+
//! 9. 有序集合 [order_set]
212
13+
pub mod rotate;
314
pub mod random;
4-
515
pub mod quick;
6-
716
pub mod kmp;
8-
917
pub mod math;
10-
11-
// 拓扑排序
1218
pub mod topological;
13-
1419
pub mod trie;
15-
1620
pub mod disjoint;
1721
pub mod order_set;

src/array/ext/disjoint.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
//! * 简单
99
//! * 中等
1010
//! * [547. 省份数量](find_circle_num)
11+
//! * [684. 冗余连接](find_redundant_connection)
12+
//! * [990. 等式方程的可满足性](equations_possible)
13+
//! * [841. 钥匙和房间](can_visit_all_rooms)
14+
//! * 困难
15+
//! * [839. 相似字符串组](num_similar_groups)
1116
//!
1217
1318
struct UnionFind {

src/array/ext/kmp.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
1+
//! KMP
2+
//!
3+
//! 暂时没有

src/array/ext/math.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,20 @@
44
//! * 简单
55
//! * [1470. 重新排列数组](shuffle)
66
//! * [1582. 二进制矩阵中的特殊位置](num_special)
7+
//! * [412. Fizz Buzz](fizz_buzz)
8+
//! * [1342. 将数字变成 0 的操作次数](number_of_steps)
9+
//! * [836. 矩形重叠](is_rectangle_overlap)
10+
//! * [867. 转置矩阵](transpose)
711
//! * 中等
812
//! * [462. 最小操作次数使数组元素相等 II](min_moves2)
913
//! * [667. 优美的排列 II](construct_array)
1014
//! * [1759. 统计同构子字符串的数目](count_homogenous)
15+
//! * [835. 图像重叠](largest_overlap)
16+
//! * [840. 矩阵中的幻方](num_magic_squares_inside)
17+
//! * [858. 镜面反射](mirror_reflection)
18+
//! * 困难
19+
//! * [829. 连续整数求和](consecutive_numbers_sum)
20+
//! * [828. 统计子串中的唯一字符](unique_letter_string)
1121
1222
/// [462. 最少移动次数使数组元素相等 II](https://leetcode.cn/problems/minimum-moves-to-equal-array-elements-ii/)
1323
///
@@ -489,11 +499,48 @@ fn lcm(a: i32, b: i32) -> i32 {
489499
a * b / gcd(a, b)
490500
}
491501

502+
/// [867. 转置矩阵](https://leetcode.cn/problems/transpose-matrix/)
503+
pub fn transpose(matrix: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
504+
let (m, n) = (matrix.len(), matrix.first().unwrap().len());
505+
let mut ret = vec![vec![0; m]; n];
506+
for i in 0..m {
507+
for j in 0..n {
508+
ret[j][i] = matrix[i][j];
509+
}
510+
}
511+
return ret;
512+
}
513+
492514
#[cfg(test)]
493515
mod tests {
494516
use super::*;
495517
use crate::vec2;
496518

519+
#[test]
520+
fn test_transpose() {
521+
struct TestCase {
522+
matrix: Vec<Vec<i32>>,
523+
expect: Vec<Vec<i32>>,
524+
}
525+
526+
vec![
527+
TestCase {
528+
matrix: vec2![[1, 2, 3], [4, 5, 6], [7, 8, 9]],
529+
expect: vec2![[1, 4, 7], [2, 5, 8], [3, 6, 9]],
530+
},
531+
TestCase {
532+
matrix: vec2![[1, 2, 3], [4, 5, 6]],
533+
expect: vec2![[1, 4], [2, 5], [3, 6]],
534+
},
535+
]
536+
.into_iter()
537+
.enumerate()
538+
.for_each(|(idx, TestCase { matrix, expect })| {
539+
let actual = transpose(matrix);
540+
assert_eq!(expect, actual, "case {} failed", idx);
541+
});
542+
}
543+
497544
#[test]
498545
#[rustfmt::skip]
499546
fn test_count_homogenous() {

0 commit comments

Comments
 (0)