From 410cacbea89e9626437447f6a7a11e7d1ab74df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E5=A2=83=E8=BF=B7=E7=A6=BB?= <568845948@qq.com> Date: Fri, 15 May 2020 19:58:15 +0800 Subject: [PATCH] refactor --- build_befor_commit.sh | 4 +- .../src/bad_safe_singly_deque.rs | 24 +- rust-datastructure/src/bad_singly_stack.rs | 2 +- rust-datastructure/src/main.rs | 4 +- rust-datastructure/src/ok_singly_stack.rs | 22 +- .../src/persistent_singly_stack.rs | 12 +- rust-datastructure/src/unsafe_singly_queue.rs | 28 +- rust-examples/src/closures.rs | 81 +-- rust-examples/src/conversion.rs | 10 +- rust-examples/src/custom_types.rs | 23 +- rust-examples/src/flow_control.rs | 61 +-- rust-examples/src/formatted_print.rs | 93 +++- rust-examples/src/functions.rs | 1 - rust-examples/src/generics.rs | 81 ++- rust-examples/src/main.rs | 16 +- rust-examples/src/misc.rs | 57 ++- rust-examples/src/modules.rs | 15 +- rust-examples/src/primitives.rs | 8 +- rust-examples/src/traits.rs | 41 +- rust-examples/src/types.rs | 2 +- rust-examples/src/variable_bindings.rs | 3 +- rust-exercise/src/closures_syntax.rs | 77 ++- rust-exercise/src/collection_function.rs | 33 +- rust-exercise/src/control_function.rs | 16 +- rust-exercise/src/enum_data_type.rs | 1 - rust-exercise/src/example_guessing_game.rs | 8 +- rust-exercise/src/front_of_house.rs | 2 +- rust-exercise/src/front_of_house/hosting.rs | 2 +- rust-exercise/src/generic_traits_lifetimes.rs | 104 ++-- rust-exercise/src/iterator_demonstration.rs | 33 +- rust-exercise/src/lib.rs | 13 +- rust-exercise/src/macro_syntax.rs | 8 +- rust-exercise/src/main.rs | 26 +- rust-exercise/src/match_syntax.rs | 5 +- rust-exercise/src/method_syntax.rs | 29 +- rust-exercise/src/other_function.rs | 19 +- rust-exercise/src/panic_function.rs | 12 +- rust-exercise/src/point_function.rs | 3 +- rust-exercise/src/simple_array_data_type.rs | 20 +- rust-exercise/src/smart_point.rs | 50 +- rust-exercise/src/struct_data_type.rs | 17 +- rust-exercise/src/thread_syntax.rs | 12 +- rust-exercise/src/variables_function.rs | 31 +- rust-http/src/lib.rs | 25 +- rust-http/src/main.rs | 4 +- rust-leetcode/README.md | 122 +++-- rust-leetcode/src/interview_01_01.rs | 34 ++ rust-leetcode/src/interview_02_02.rs | 49 ++ rust-leetcode/src/interview_03_04.rs | 51 ++ rust-leetcode/src/interview_04_02.rs | 25 + rust-leetcode/src/interview_05.rs | 9 + rust-leetcode/src/interview_06.rs | 19 + rust-leetcode/src/interview_09.rs | 38 ++ rust-leetcode/src/interview_16_07.rs | 14 + rust-leetcode/src/interview_17.rs | 49 ++ rust-leetcode/src/interview_22.rs | 28 ++ rust-leetcode/src/interview_24.rs | 20 + rust-leetcode/src/interview_25.rs | 58 +++ rust-leetcode/src/interview_27.rs | 27 + rust-leetcode/src/interview_32_2.rs | 45 ++ rust-leetcode/src/interview_54.rs | 28 ++ rust-leetcode/src/interview_55_1.rs | 20 + rust-leetcode/src/interview_58_2.rs | 11 + rust-leetcode/src/leetcode_1021.rs | 43 ++ rust-leetcode/src/leetcode_1051.rs | 17 + rust-leetcode/src/leetcode_108.rs | 22 + rust-leetcode/src/leetcode_1160.rs | 31 ++ rust-leetcode/src/leetcode_1207.rs | 32 ++ rust-leetcode/src/leetcode_1221.rs | 31 ++ rust-leetcode/src/leetcode_1252.rs | 25 + rust-leetcode/src/leetcode_1281.rs | 17 + rust-leetcode/src/leetcode_13.rs | 87 ++++ rust-leetcode/src/leetcode_1304.rs | 36 ++ rust-leetcode/src/leetcode_1313.rs | 19 + rust-leetcode/src/leetcode_1323.rs | 8 + rust-leetcode/src/leetcode_1342.rs | 18 + rust-leetcode/src/leetcode_1351.rs | 13 + rust-leetcode/src/leetcode_1365.rs | 18 + rust-leetcode/src/leetcode_1370.rs | 27 + rust-leetcode/src/leetcode_1374.rs | 18 + rust-leetcode/src/leetcode_1380.rs | 32 ++ rust-leetcode/src/leetcode_1385.rs | 22 + rust-leetcode/src/leetcode_14.rs | 79 +++ rust-leetcode/src/leetcode_1403.rs | 19 + rust-leetcode/src/leetcode_1413.rs | 20 + rust-leetcode/src/leetcode_20.rs | 28 ++ rust-leetcode/src/leetcode_292.rs | 12 + rust-leetcode/src/leetcode_35.rs | 22 + rust-leetcode/src/leetcode_38.rs | 50 ++ rust-leetcode/src/leetcode_461.rs | 17 + rust-leetcode/src/leetcode_500.rs | 52 ++ rust-leetcode/src/leetcode_557.rs | 16 + rust-leetcode/src/leetcode_561.rs | 17 + rust-leetcode/src/leetcode_58.rs | 17 + rust-leetcode/src/leetcode_617.rs | 65 +++ rust-leetcode/src/leetcode_665.rs | 40 ++ rust-leetcode/src/leetcode_709.rs | 17 + rust-leetcode/src/leetcode_728.rs | 24 + rust-leetcode/src/leetcode_804.rs | 25 + rust-leetcode/src/leetcode_832.rs | 22 + rust-leetcode/src/leetcode_859.rs | 58 +++ rust-leetcode/src/leetcode_876.rs | 14 + rust-leetcode/src/leetcode_9.rs | 39 ++ rust-leetcode/src/leetcode_905.rs | 18 + rust-leetcode/src/leetcode_933.rs | 26 + rust-leetcode/src/leetcode_938.rs | 52 ++ rust-leetcode/src/leetcode_942.rs | 24 + rust-leetcode/src/leetcode_944.rs | 23 + rust-leetcode/src/leetcode_977.rs | 30 ++ rust-leetcode/src/leetcode_999.rs | 43 ++ rust-leetcode/src/main.rs | 69 ++- .../src/{Solution.rs => old_solutions.rs} | 469 +++++++++++++----- rust-leetcode/src/pre_structs.rs | 37 ++ rust-minigrep/src/lib.rs | 38 +- rust-minigrep/src/main.rs | 15 +- rust-oop/src/lib.rs | 5 +- rust-oop/src/main.rs | 5 +- rust-oop/src/oop_blog.rs | 2 +- rust-oop/src/rust_blog.rs | 2 +- 119 files changed, 3093 insertions(+), 719 deletions(-) create mode 100644 rust-leetcode/src/interview_01_01.rs create mode 100644 rust-leetcode/src/interview_02_02.rs create mode 100644 rust-leetcode/src/interview_03_04.rs create mode 100644 rust-leetcode/src/interview_04_02.rs create mode 100644 rust-leetcode/src/interview_05.rs create mode 100644 rust-leetcode/src/interview_06.rs create mode 100644 rust-leetcode/src/interview_09.rs create mode 100644 rust-leetcode/src/interview_16_07.rs create mode 100644 rust-leetcode/src/interview_17.rs create mode 100644 rust-leetcode/src/interview_22.rs create mode 100644 rust-leetcode/src/interview_24.rs create mode 100644 rust-leetcode/src/interview_25.rs create mode 100644 rust-leetcode/src/interview_27.rs create mode 100644 rust-leetcode/src/interview_32_2.rs create mode 100644 rust-leetcode/src/interview_54.rs create mode 100644 rust-leetcode/src/interview_55_1.rs create mode 100644 rust-leetcode/src/interview_58_2.rs create mode 100644 rust-leetcode/src/leetcode_1021.rs create mode 100644 rust-leetcode/src/leetcode_1051.rs create mode 100644 rust-leetcode/src/leetcode_108.rs create mode 100644 rust-leetcode/src/leetcode_1160.rs create mode 100644 rust-leetcode/src/leetcode_1207.rs create mode 100644 rust-leetcode/src/leetcode_1221.rs create mode 100644 rust-leetcode/src/leetcode_1252.rs create mode 100644 rust-leetcode/src/leetcode_1281.rs create mode 100644 rust-leetcode/src/leetcode_13.rs create mode 100644 rust-leetcode/src/leetcode_1304.rs create mode 100644 rust-leetcode/src/leetcode_1313.rs create mode 100644 rust-leetcode/src/leetcode_1323.rs create mode 100644 rust-leetcode/src/leetcode_1342.rs create mode 100644 rust-leetcode/src/leetcode_1351.rs create mode 100644 rust-leetcode/src/leetcode_1365.rs create mode 100644 rust-leetcode/src/leetcode_1370.rs create mode 100644 rust-leetcode/src/leetcode_1374.rs create mode 100644 rust-leetcode/src/leetcode_1380.rs create mode 100644 rust-leetcode/src/leetcode_1385.rs create mode 100644 rust-leetcode/src/leetcode_14.rs create mode 100644 rust-leetcode/src/leetcode_1403.rs create mode 100644 rust-leetcode/src/leetcode_1413.rs create mode 100644 rust-leetcode/src/leetcode_20.rs create mode 100644 rust-leetcode/src/leetcode_292.rs create mode 100644 rust-leetcode/src/leetcode_35.rs create mode 100644 rust-leetcode/src/leetcode_38.rs create mode 100644 rust-leetcode/src/leetcode_461.rs create mode 100644 rust-leetcode/src/leetcode_500.rs create mode 100644 rust-leetcode/src/leetcode_557.rs create mode 100644 rust-leetcode/src/leetcode_561.rs create mode 100644 rust-leetcode/src/leetcode_58.rs create mode 100644 rust-leetcode/src/leetcode_617.rs create mode 100644 rust-leetcode/src/leetcode_665.rs create mode 100644 rust-leetcode/src/leetcode_709.rs create mode 100644 rust-leetcode/src/leetcode_728.rs create mode 100644 rust-leetcode/src/leetcode_804.rs create mode 100644 rust-leetcode/src/leetcode_832.rs create mode 100644 rust-leetcode/src/leetcode_859.rs create mode 100644 rust-leetcode/src/leetcode_876.rs create mode 100644 rust-leetcode/src/leetcode_9.rs create mode 100644 rust-leetcode/src/leetcode_905.rs create mode 100644 rust-leetcode/src/leetcode_933.rs create mode 100644 rust-leetcode/src/leetcode_938.rs create mode 100644 rust-leetcode/src/leetcode_942.rs create mode 100644 rust-leetcode/src/leetcode_944.rs create mode 100644 rust-leetcode/src/leetcode_977.rs create mode 100644 rust-leetcode/src/leetcode_999.rs rename rust-leetcode/src/{Solution.rs => old_solutions.rs} (85%) create mode 100644 rust-leetcode/src/pre_structs.rs diff --git a/build_befor_commit.sh b/build_befor_commit.sh index f91e8c12..27760f93 100644 --- a/build_befor_commit.sh +++ b/build_befor_commit.sh @@ -21,11 +21,11 @@ do echo "############ [ not enable $lang language in this project ]" break fi - # compile rust + # compile rust and fmt code case "$lang" in "rust") echo "################# [ compile $sub_module ]" - `cd $sub_module;cargo build >/dev/null 2>&1 ;cd .. `;; + `cd $sub_module;cargo build >/dev/null 2>&1;cargo fmt --all; cd .. `;; # compile python "python") echo "############ [ TODO ]";; diff --git a/rust-datastructure/src/bad_safe_singly_deque.rs b/rust-datastructure/src/bad_safe_singly_deque.rs index 0892c9b5..ab807392 100644 --- a/rust-datastructure/src/bad_safe_singly_deque.rs +++ b/rust-datastructure/src/bad_safe_singly_deque.rs @@ -19,7 +19,6 @@ struct Node { prev: Link, } - impl Node { fn new(elem: T) -> Rc> { Rc::new(RefCell::new(Node { @@ -32,7 +31,10 @@ impl Node { impl List { pub fn new() -> Self { - List { head: None, tail: None } + List { + head: None, + tail: None, + } } pub fn push_front(&mut self, elem: T) { @@ -116,23 +118,23 @@ impl List { //获取尾结点的不可变引用 pub fn peek_back(&self) -> Option> { - self.tail.as_ref().map(|node| { - Ref::map(node.borrow(), |node| &node.elem) - }) + self.tail + .as_ref() + .map(|node| Ref::map(node.borrow(), |node| &node.elem)) } //获取尾结点的可变引用 pub fn peek_back_mut(&mut self) -> Option> { - self.tail.as_ref().map(|node| { - RefMut::map(node.borrow_mut(), |node| &mut node.elem) - }) + self.tail + .as_ref() + .map(|node| RefMut::map(node.borrow_mut(), |node| &mut node.elem)) } //获取头结点的可变引用 pub fn peek_front_mut(&mut self) -> Option> { - self.head.as_ref().map(|node| { - RefMut::map(node.borrow_mut(), |node| &mut node.elem) - }) + self.head + .as_ref() + .map(|node| RefMut::map(node.borrow_mut(), |node| &mut node.elem)) } //需要所有权的迭代器 diff --git a/rust-datastructure/src/bad_singly_stack.rs b/rust-datastructure/src/bad_singly_stack.rs index a92efc50..8c05f9a5 100644 --- a/rust-datastructure/src/bad_singly_stack.rs +++ b/rust-datastructure/src/bad_singly_stack.rs @@ -86,4 +86,4 @@ mod test { assert_eq!(list.pop(), Some(1)); assert_eq!(list.pop(), None); } -} \ No newline at end of file +} diff --git a/rust-datastructure/src/main.rs b/rust-datastructure/src/main.rs index 204e5835..d3d56f28 100644 --- a/rust-datastructure/src/main.rs +++ b/rust-datastructure/src/main.rs @@ -1,7 +1,7 @@ +pub mod bad_safe_singly_deque; pub mod bad_singly_stack; pub mod ok_singly_stack; pub mod persistent_singly_stack; -pub mod bad_safe_singly_deque; pub mod unsafe_singly_queue; -pub fn main() {} \ No newline at end of file +pub fn main() {} diff --git a/rust-datastructure/src/ok_singly_stack.rs b/rust-datastructure/src/ok_singly_stack.rs index 755471be..865e8085 100644 --- a/rust-datastructure/src/ok_singly_stack.rs +++ b/rust-datastructure/src/ok_singly_stack.rs @@ -36,16 +36,12 @@ impl List { //获取第一个元素的不可变引用 pub fn peek(&self) -> Option<&T> { - self.head.as_ref().map(|node| { - &node.elem - }) + self.head.as_ref().map(|node| &node.elem) } //获取第一个元素的可变引用 pub fn peek_mut(&mut self) -> Option<&mut T> { - self.head.as_mut().map(|node| { - &mut node.elem - }) + self.head.as_mut().map(|node| &mut node.elem) } pub fn into_iter(self) -> IntoIter { @@ -53,11 +49,15 @@ impl List { } pub fn iter(&self) -> Iter<'_, T> { - Iter { next: self.head.as_ref().map(|node| &**node) } + Iter { + next: self.head.as_ref().map(|node| &**node), + } } pub fn iter_mut(&mut self) -> IterMut<'_, T> { - IterMut { next: self.head.as_mut().map(|node| &mut **node) } + IterMut { + next: self.head.as_mut().map(|node| &mut **node), + } } } @@ -150,9 +150,7 @@ mod test { assert_eq!(list.peek(), Some(&3)); assert_eq!(list.peek_mut(), Some(&mut 3)); - list.peek_mut().map(|value| { - *value = 42 - }); + list.peek_mut().map(|value| *value = 42); assert_eq!(list.peek(), Some(&42)); assert_eq!(list.pop(), Some(42)); @@ -197,4 +195,4 @@ mod test { assert_eq!(iter.next(), Some(&mut 2)); assert_eq!(iter.next(), Some(&mut 1)); } -} \ No newline at end of file +} diff --git a/rust-datastructure/src/persistent_singly_stack.rs b/rust-datastructure/src/persistent_singly_stack.rs index 4f1d2657..9e225825 100644 --- a/rust-datastructure/src/persistent_singly_stack.rs +++ b/rust-datastructure/src/persistent_singly_stack.rs @@ -25,13 +25,15 @@ impl List { head: Some(Rc::new(Node { elem, next: self.head.clone(), - })) + })), } } pub fn tail(&self) -> List { //and_then 如果self为[`None`],则返回[`None`],否则调用'f'并包装值,返回结果。有些语言称此操作为flatmap。 - List { head: self.head.as_ref().and_then(|node| node.next.clone()) } + List { + head: self.head.as_ref().and_then(|node| node.next.clone()), + } } pub fn head(&self) -> Option<&T> { @@ -39,7 +41,9 @@ impl List { } pub fn iter(&self) -> Iter<'_, T> { - Iter { next: self.head.as_ref().map(|node| &**node) } + Iter { + next: self.head.as_ref().map(|node| &**node), + } } } @@ -104,4 +108,4 @@ mod test { assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next(), Some(&1)); } -} \ No newline at end of file +} diff --git a/rust-datastructure/src/unsafe_singly_queue.rs b/rust-datastructure/src/unsafe_singly_queue.rs index d3bd867d..483c7485 100644 --- a/rust-datastructure/src/unsafe_singly_queue.rs +++ b/rust-datastructure/src/unsafe_singly_queue.rs @@ -17,14 +17,14 @@ struct Node { impl List { pub fn new() -> Self { //创建一个空的可变的原始行指针 - List { head: None, tail: ptr::null_mut() } + List { + head: None, + tail: ptr::null_mut(), + } } pub fn push(&mut self, elem: T) { - let mut new_tail = Box::new(Node { - elem, - next: None, - }); + let mut new_tail = Box::new(Node { elem, next: None }); //强制为原始指针 let raw_tail: *mut _ = &mut *new_tail; @@ -54,15 +54,11 @@ impl List { } pub fn peek(&self) -> Option<&T> { - self.head.as_ref().map(|node| { - &node.elem - }) + self.head.as_ref().map(|node| &node.elem) } pub fn peek_mut(&mut self) -> Option<&mut T> { - self.head.as_mut().map(|node| { - &mut node.elem - }) + self.head.as_mut().map(|node| &mut node.elem) } pub fn into_iter(self) -> IntoIter { @@ -70,11 +66,15 @@ impl List { } pub fn iter(&self) -> Iter<'_, T> { - Iter { next: self.head.as_ref().map(|node| &**node) } + Iter { + next: self.head.as_ref().map(|node| &**node), + } } pub fn iter_mut(&mut self) -> IterMut<'_, T> { - IterMut { next: self.head.as_mut().map(|node| &mut **node) } + IterMut { + next: self.head.as_mut().map(|node| &mut **node), + } } } @@ -201,4 +201,4 @@ mod test { assert_eq!(iter.next(), Some(&mut 3)); assert_eq!(iter.next(), None); } -} \ No newline at end of file +} diff --git a/rust-examples/src/closures.rs b/rust-examples/src/closures.rs index d846a6a5..9a21009e 100644 --- a/rust-examples/src/closures.rs +++ b/rust-examples/src/closures.rs @@ -4,7 +4,9 @@ //by value: T pub fn closures() { //闭包是lambda,一个表达式可以省略大括号 - fn function(i: i32) -> i32 { i + 1 } + fn function(i: i32) -> i32 { + i + 1 + } let closure_annotated = |i: i32| -> i32 { i + 1 }; let closure_inferred = |i| i + 1; let i = 1; @@ -35,10 +37,10 @@ fn capturing() { let print = || println!("`color`: {}", color); print(); - let _reborrow = &color;//闭包使用的color能被继续借用 - print();//直到最后一次使用print + let _reborrow = &color; //闭包使用的color能被继续借用 + print(); //直到最后一次使用print - let _color_moved = color;//最后使用`print`后允许移动或重新借用 + let _color_moved = color; //最后使用`print`后允许移动或重新借用 let mut count = 0; let mut inc = || { count += 1; @@ -55,20 +57,26 @@ fn capturing() { mem::drop(movable); }; - consume();//仅能被使用一次。 + consume(); //仅能被使用一次。 } fn input_parameters() { //以闭包作为参数并调用它的函数。 - fn apply(f: F) where - // The closure takes no input and returns nothing. - F: FnOnce() {//按值捕获 + fn apply(f: F) + where + // The closure takes no input and returns nothing. + F: FnOnce(), + { + //按值捕获 // ^ TODO: Try changing this to `Fn` or `FnMut`. f(); } // A function which takes a closure and returns an `i32`. - fn apply_to_3(f: F) -> i32 where F: Fn(i32) -> i32 { + fn apply_to_3(f: F) -> i32 + where + F: Fn(i32) -> i32, + { f(3) } @@ -78,11 +86,11 @@ fn input_parameters() { //从借来的引用创建自己拥有的数据 let mut farewell = "goodbye".to_owned(); let diary = || { - println!("I said {}.", greeting);//捕获引用 - farewell.push_str("!!!");//捕获可变引用 + println!("I said {}.", greeting); //捕获引用 + farewell.push_str("!!!"); //捕获可变引用 println!("Then I screamed {}.", farewell); println!("Now I can sleep. zzzzz"); - mem::drop(farewell);//捕获值 + mem::drop(farewell); //捕获值 }; apply(diary); let double = |x| 2 * x; @@ -91,8 +99,10 @@ fn input_parameters() { fn type_anonymity() { // `F`必须是泛型的 - fn apply(f: F) where - F: FnOnce() { + fn apply(f: F) + where + F: FnOnce(), + { f(); } } @@ -145,8 +155,8 @@ fn closures_std() { //any let vec1 = vec![1, 2, 3]; let vec2 = vec![4, 5, 6]; - println!("2 in vec1: {}", vec1.iter().any(|&x| x == 2));//不消耗集合,使用引用捕获 - println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2));//消耗集合,使用值捕获 + println!("2 in vec1: {}", vec1.iter().any(|&x| x == 2)); //不消耗集合,使用引用捕获 + println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2)); //消耗集合,使用值捕获 let array1 = [1, 2, 3]; let array2 = [4, 5, 6]; println!("2 in array1: {}", array1.iter().any(|&x| x == 2)); @@ -155,16 +165,19 @@ fn closures_std() { //find let vec1 = vec![1, 2, 3]; let vec2 = vec![4, 5, 6]; - let mut iter = vec1.iter();//&i32 - let mut into_iter = vec2.into_iter();//i32 - //解构参数 - println!("Find 2 in vec1: {:?}", iter.find(|&&x| x == 2));//`&&i32` to `i32` - println!("Find 2 in vec1: {:?}", iter.find(|x| **x == 2));//参数是`&&i32`,使用时解构 - println!("Find 2 in vec2: {:?}", into_iter.find(|&x| x == 2));//`&i32` to `i32` + let mut iter = vec1.iter(); //&i32 + let mut into_iter = vec2.into_iter(); //i32 + //解构参数 + println!("Find 2 in vec1: {:?}", iter.find(|&&x| x == 2)); //`&&i32` to `i32` + println!("Find 2 in vec1: {:?}", iter.find(|x| **x == 2)); //参数是`&&i32`,使用时解构 + println!("Find 2 in vec2: {:?}", into_iter.find(|&x| x == 2)); //`&i32` to `i32` let array1 = [1, 2, 3]; let array2 = [4, 5, 6]; println!("Find 2 in array1: {:?}", array1.iter().find(|&&x| x == 2)); - println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2)); + println!( + "Find 2 in array2: {:?}", + array2.into_iter().find(|&&x| x == 2) + ); //position index let vec = vec![1, 9, 3, 3, 13, 2]; @@ -185,7 +198,8 @@ fn higher_order_functions() { println!("Find the sum of all the squared odd numbers under 1000"); let upper = 1000; let mut acc = 0; - for n in 0.. {//无穷大 + for n in 0.. { + //无穷大 let n_squared = n * n; if n_squared >= upper { break; @@ -195,11 +209,11 @@ fn higher_order_functions() { } println!("imperative style: {}", acc); //函数式风格 - let sum_of_squared_odd_numbers: u32 = - (0..).map(|n| n * n) - .take_while(|&n_squared| n_squared < upper) - .filter(|&n_squared| is_odd(n_squared)) // That are odd - .fold(0, |acc, n_squared| acc + n_squared); // Sum them + let sum_of_squared_odd_numbers: u32 = (0..) + .map(|n| n * n) + .take_while(|&n_squared| n_squared < upper) + .filter(|&n_squared| is_odd(n_squared)) // That are odd + .fold(0, |acc, n_squared| acc + n_squared); // Sum them println!("functional style: {}", sum_of_squared_odd_numbers); } @@ -222,13 +236,16 @@ fn diverging_functions() { for i in 0..up_to { let addition: u32 = match i % 2 == 1 { true => i, - false => continue,//不返还,不违反match + false => continue, //不返还,不违反match }; acc += addition; } acc } - println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9)); + println!( + "Sum of odd numbers up to 9 (excluding): {}", + sum_odd_numbers(9) + ); //println!("{}", foo()) //error This call never returns. -} \ No newline at end of file +} diff --git a/rust-examples/src/conversion.rs b/rust-examples/src/conversion.rs index e87e9154..a50e9dcf 100644 --- a/rust-examples/src/conversion.rs +++ b/rust-examples/src/conversion.rs @@ -1,6 +1,5 @@ ///类型之间的转化 pub fn conversion() { - //FROM let my_str = "hello"; let my_string = String::from(my_str); @@ -25,7 +24,6 @@ pub fn conversion() { let num: Number = int.into(); println!("My number is {:?}", num); - try_conversion(); //转化为整数 @@ -64,11 +62,10 @@ fn try_conversion() { let result: Result = 5i32.try_into(); assert_eq!(result, Err(())); - //转化为字符串 use std::fmt; struct Circle { - radius: i32 + radius: i32, } impl fmt::Display for Circle { @@ -86,16 +83,15 @@ fn expression() { let y = { let x_squared = x * x; let x_cube = x_squared * x; - x_cube + x_squared + x//返回这个表达式 + x_cube + x_squared + x //返回这个表达式 }; let z = { // The semicolon suppresses this expression and `()` is assigned to `z` - 2 * x;//以分号结尾的返回 () + 2 * x; //以分号结尾的返回 () }; println!("x is {:?}", x); println!("y is {:?}", y); println!("z is {:?}", z); } - diff --git a/rust-examples/src/custom_types.rs b/rust-examples/src/custom_types.rs index 00090339..a3471b26 100644 --- a/rust-examples/src/custom_types.rs +++ b/rust-examples/src/custom_types.rs @@ -53,11 +53,17 @@ fn structures() { println!("second point: ({}, {})", bottom_right.x, bottom_right.y); //使用“let”绑定对点进行解构 - let Point { x: top_edge, y: left_edge } = point; + let Point { + x: top_edge, + y: left_edge, + } = point; let _rectangle = Rectangle { //结构体实例也是一个表达式 - top_left: Point { x: left_edge, y: top_edge }, + top_left: Point { + x: left_edge, + y: top_edge, + }, bottom_right: bottom_right, }; @@ -115,7 +121,6 @@ fn enums() { inspect(load); inspect(unload); - ///类型别名 enum VeryVerboseEnumOfThingsToDoWithNumbers { Add, @@ -137,7 +142,6 @@ fn enums() { } } - enum Status { Rich, Poor, @@ -163,7 +167,6 @@ fn enums() { Soldier => println!("Soldiers fight!"), } - ///经典的类c结构体 enum Number { Zero, @@ -213,7 +216,7 @@ fn testcase_linkedlist() { match *self { //不能拥有尾,因为“self”是借来的;相反,要引用尾 Cons(_, ref tail) => 1 + tail.len(), - Nil => 0 + Nil => 0, } } @@ -224,9 +227,7 @@ fn testcase_linkedlist() { //返回堆分配的字符串,而不是打印到控制台 format!("{}, {}", head, tail.stringify()) } - Nil => { - format!("Nil") - } + Nil => format!("Nil"), } } } @@ -238,7 +239,7 @@ fn testcase_linkedlist() { list = list.prepend(3); println!("linked list has length: {}", list.len()); - println!("{}", list.stringify());//3, 2, 1, Nil + println!("{}", list.stringify()); //3, 2, 1, Nil } pub fn constants() { @@ -262,4 +263,4 @@ pub fn constants() { // Error! Cannot modify a `const`. //THRESHOLD = 5; // FIXME ^ Comment out this line -} \ No newline at end of file +} diff --git a/rust-examples/src/flow_control.rs b/rust-examples/src/flow_control.rs index d03be894..870729fa 100644 --- a/rust-examples/src/flow_control.rs +++ b/rust-examples/src/flow_control.rs @@ -31,7 +31,7 @@ fn if_else() { } else { println!(", and is a big number, halve the number"); n / 2 - };//别忘了在这里加分号!所有“let”绑定都需要它 + }; //别忘了在这里加分号!所有“let”绑定都需要它 println!("{} -> {}", n, big_n); } @@ -61,12 +61,11 @@ fn loop_while() { println!("Entered the inner loop"); break 'outer; } - println!("This point will never be reached");//永远不会被执行,到break 'outer;就会直接退出外层循环 + println!("This point will never be reached"); //永远不会被执行,到break 'outer;就会直接退出外层循环 } println!("Exited the outer loop"); - //从loop返回值 let mut counter = 0; @@ -99,7 +98,8 @@ fn loop_while() { fn for_range() { //`n` = 1, 2, ..., 100 - for n in 1..101 {//包含左,不含右,Scala的until不包含右界,to包含右界 + for n in 1..101 { + //包含左,不含右,Scala的until不包含右界,to包含右界 if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { @@ -112,7 +112,8 @@ fn for_range() { } //`n` = 1, 2, ..., 100 - for n in 1..=100 {//包含右界 + for n in 1..=100 { + //包含右界 if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { @@ -126,7 +127,8 @@ fn for_range() { ///迭代器 let names = vec!["Bob", "Frank", "Ferris"]; - for name in names.iter() {//将在每次迭代中借用集合的每个元素。因此,在循环之后,该集合将保持不变并可供重用。 + for name in names.iter() { + //将在每次迭代中借用集合的每个元素。因此,在循环之后,该集合将保持不变并可供重用。 match name { &"Ferris" => println!("There is a rustacean among us!"), _ => println!("Hello {}", name), @@ -134,7 +136,8 @@ fn for_range() { } let names = vec!["Bob", "Frank", "Ferris"]; - for name in names.into_iter() {//消耗集合,以便在每次迭代时提供准确的数据。一旦使用完了集合,就不再可以重复使用,因为它已在循环中“移动”。 + for name in names.into_iter() { + //消耗集合,以便在每次迭代时提供准确的数据。一旦使用完了集合,就不再可以重复使用,因为它已在循环中“移动”。 match name { "Ferris" => println!("There is a rustacean among us!"), _ => println!("Hello {}", name), @@ -142,7 +145,8 @@ fn for_range() { } let mut names = vec!["Bob", "Frank", "Ferris"]; - for name in names.iter_mut() {//可变地借用了集合的每个元素,从而允许在适当的位置修改集合。 + for name in names.iter_mut() { + //可变地借用了集合的每个元素,从而允许在适当的位置修改集合。 *name = match name { &mut "Ferris" => "There is a rustacean among us!", _ => "Hello", @@ -156,10 +160,10 @@ fn match_case() { let number = 13; println!("Tell me about {}", number); match number { - 1 => println!("One!"),//仅匹配1 - 2 | 3 | 5 | 7 | 11 => println!("This is a prime"),//匹配2或3或5或7或11 - 13..=19 => println!("A teen"),//匹配13到19的数字 - _ => println!("Ain't special"),//其他 + 1 => println!("One!"), //仅匹配1 + 2 | 3 | 5 | 7 | 11 => println!("This is a prime"), //匹配2或3或5或7或11 + 13..=19 => println!("A teen"), //匹配13到19的数字 + _ => println!("Ain't special"), //其他 } let boolean = true; @@ -202,17 +206,14 @@ fn match_enums() { Color::Red => println!("The color is Red!"), Color::Blue => println!("The color is Blue!"), Color::Green => println!("The color is Green!"), - Color::RGB(r, g, b) => - println!("Red: {}, green: {}, and blue: {}!", r, g, b), - Color::HSV(h, s, v) => - println!("Hue: {}, saturation: {}, value: {}!", h, s, v), - Color::HSL(h, s, l) => - println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l), - Color::CMY(c, m, y) => - println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y), - Color::CMYK(c, m, y, k) => - println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!", - c, m, y, k), + Color::RGB(r, g, b) => println!("Red: {}, green: {}, and blue: {}!", r, g, b), + Color::HSV(h, s, v) => println!("Hue: {}, saturation: {}, value: {}!", h, s, v), + Color::HSL(h, s, l) => println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l), + Color::CMY(c, m, y) => println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y), + Color::CMYK(c, m, y, k) => println!( + "Cyan: {}, magenta: {}, yellow: {}, key (black): {}!", + c, m, y, k + ), } } @@ -321,7 +322,8 @@ fn if_let() { if let Some(i) = emoticon { println!("Matched {:?}!", i); - } else if i_like_letters {//lf let没匹配上 + } else if i_like_letters { + //lf let没匹配上 println!("Didn't match a number. Let's go with a letter!"); } else { println!("I don't like letters. Let's go with an emoticon :)!"); @@ -352,7 +354,8 @@ fn if_let() { } let a = Foo::Bar; - if let Foo::Bar = a {//枚举没有注解#[derive(PartialEq)],则无法比较,使用传统的if,则失败,编译不过 + if let Foo::Bar = a { + //枚举没有注解#[derive(PartialEq)],则无法比较,使用传统的if,则失败,编译不过 println!("a is foobar"); } } @@ -371,7 +374,9 @@ fn while_let() { optional = Some(i + 1); } } - _ => { break; } + _ => { + break; + } } } @@ -385,5 +390,5 @@ fn while_let() { println!("`i` is `{:?}`. Try again.", i); optional = Some(i + 1); } - }//while let 无子语句 -} \ No newline at end of file + } //while let 无子语句 +} diff --git a/rust-examples/src/formatted_print.rs b/rust-examples/src/formatted_print.rs index ec18ec53..ceb0ebdb 100644 --- a/rust-examples/src/formatted_print.rs +++ b/rust-examples/src/formatted_print.rs @@ -1,5 +1,5 @@ -use std::fmt::{Display, Error, Formatter}; use std::fmt; +use std::fmt::{Display, Error, Formatter}; ///println宏的使用 pub fn formatted_print() { @@ -7,9 +7,17 @@ pub fn formatted_print() { println!("{} days", 31); println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); //命名参数 - println!("{subject} {verb} {object}", object = "the lazy dog", subject = "the quick brown fox", verb = "jumps over"); + println!( + "{subject} {verb} {object}", + object = "the lazy dog", + subject = "the quick brown fox", + verb = "jumps over" + ); // 在冒号后指定特殊输出格式 - println!("{} of {:b} people know binary, the other half doesn't", 1, 2); + println!( + "{} of {:b} people know binary, the other half doesn't", + 1, 2 + ); //右对齐,指定宽度6 println!("{number:>width$}", number = 1, width = 6); //右对齐,宽度6,使用0填错 @@ -30,12 +38,14 @@ pub fn formatted_print() { } //更好看 - let peter = Person { name: "Peter", age: 27 }; + let peter = Person { + name: "Peter", + age: 27, + }; println!("{:#?}", peter); //自己实现fmt::Display或Debug特质 - #[derive(Debug)] struct MinMax(i64, i64); @@ -61,7 +71,11 @@ pub fn formatted_print() { //实现自己的Debug impl fmt::Debug for Point2D { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { - write!(f, "Complex {} real: {}, imag: {} {}", "{", self.x, self.y, "}") + write!( + f, + "Complex {} real: {}, imag: {} {}", + "{", self.x, self.y, "}" + ) } } @@ -75,7 +89,6 @@ pub fn formatted_print() { println!("Debug: {:?}", point); println!("Debug: {:?}", point); - testcase_list(); struct City { @@ -88,7 +101,15 @@ pub fn formatted_print() { fn fmt(&self, f: &mut Formatter) -> fmt::Result { let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' }; let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' }; - write!(f, "{}: {:.3}°{} {:.3}°{}", self.name, self.lat.abs(), lat_c, self.lon.abs(), lon_c) + write!( + f, + "{}: {:.3}°{} {:.3}°{}", + self.name, + self.lat.abs(), + lat_c, + self.lon.abs(), + lon_c + ) } } @@ -107,23 +128,55 @@ pub fn formatted_print() { //format!("{}", foo) -> "3735928559" //format!("0x{:X}", foo) -> "0xDEADBEEF" //format!("0o{:o}", foo) -> "0o33653337357" - write!(f, "RGB ({}, {}, {}) 0x{:0>2X}{:0>2X}{:0>2X} ", self.red, self.green, self.blue, self.red, self.green, self.blue) + write!( + f, + "RGB ({}, {}, {}) 0x{:0>2X}{:0>2X}{:0>2X} ", + self.red, self.green, self.blue, self.red, self.green, self.blue + ) //右对齐,补0,16进制打印 } } for city in [ - City { name: "Dublin", lat: 53.347778, lon: -6.259722 }, - City { name: "Oslo", lat: 59.95, lon: 10.75 }, - City { name: "Vancouver", lat: 49.25, lon: -123.1 }, - ].iter() { + City { + name: "Dublin", + lat: 53.347778, + lon: -6.259722, + }, + City { + name: "Oslo", + lat: 59.95, + lon: 10.75, + }, + City { + name: "Vancouver", + lat: 49.25, + lon: -123.1, + }, + ] + .iter() + { println!("{}", *city); } for color in [ - Color { red: 128, green: 255, blue: 90 }, - Color { red: 0, green: 3, blue: 254 }, - Color { red: 0, green: 0, blue: 0 }, - ].iter() { + Color { + red: 128, + green: 255, + blue: 90, + }, + Color { + red: 0, + green: 3, + blue: 254, + }, + Color { + red: 0, + green: 0, + blue: 0, + }, + ] + .iter() + { println!("{:#}", *color); } } @@ -137,8 +190,10 @@ pub fn testcase_list() { let vec = &self.0; write!(f, "[")?; for (count, v) in vec.iter().enumerate() { - if count != 0 { write!(f, ", ")?; } - write!(f, "{}: {}", count, v)?;//打印索引和数据 + if count != 0 { + write!(f, ", ")?; + } + write!(f, "{}: {}", count, v)?; //打印索引和数据 } write!(f, "]") } diff --git a/rust-examples/src/functions.rs b/rust-examples/src/functions.rs index a5b41b5a..75dc653e 100644 --- a/rust-examples/src/functions.rs +++ b/rust-examples/src/functions.rs @@ -107,4 +107,3 @@ fn methods() { pair.destroy(); } - diff --git a/rust-examples/src/generics.rs b/rust-examples/src/generics.rs index 46d86b33..9467ac87 100644 --- a/rust-examples/src/generics.rs +++ b/rust-examples/src/generics.rs @@ -103,22 +103,38 @@ fn bounds() { fn area(&self) -> f64; } impl HasArea for Rectangle { - fn area(&self) -> f64 { self.length * self.height } + fn area(&self) -> f64 { + self.length * self.height + } } #[derive(Debug)] - struct Rectangle { length: f64, height: f64 } + struct Rectangle { + length: f64, + height: f64, + } #[allow(dead_code)] - struct Triangle { length: f64, height: f64 } + struct Triangle { + length: f64, + height: f64, + } //泛型“T”必须实现“Debug” fn print_debug(t: &T) { println!("{:?}", t); } //必须实现HasArea - fn area(t: &T) -> f64 { t.area() } + fn area(t: &T) -> f64 { + t.area() + } - let rectangle = Rectangle { length: 3.0, height: 4.0 }; - let _triangle = Triangle { length: 3.0, height: 4.0 }; + let rectangle = Rectangle { + length: 3.0, + height: 4.0, + }; + let _triangle = Triangle { + length: 3.0, + height: 4.0, + }; print_debug(&rectangle); println!("Area: {}", area(&rectangle)); //print_debug(&_triangle); @@ -136,8 +152,12 @@ fn bounds() { impl Blue for BlueJay {} //这些函数仅对实现这些特性的类型有效。这些特征都是空的,这一事实无关紧要。 - fn red(_: &T) -> &'static str { "red" } - fn blue(_: &T) -> &'static str { "blue" } + fn red(_: &T) -> &'static str { + "red" + } + fn blue(_: &T) -> &'static str { + "blue" + } let cardinal = Cardinal; let blue_jay = BlueJay; let _turkey = Turkey; @@ -175,7 +195,10 @@ fn where_clauses() { fn print_in_option(self); } - impl PrintInOption for T where Option: Debug { + impl PrintInOption for T + where + Option: Debug, + { fn print_in_option(self) { println!("{:?}", Some(self)); } @@ -200,18 +223,29 @@ fn associated_types() { fn contains(&self, number_1: &i32, number_2: &i32) -> bool { (&self.0 == number_1) && (&self.1 == number_2) } - fn first(&self) -> i32 { self.0 } - fn last(&self) -> i32 { self.1 } + fn first(&self) -> i32 { + self.0 + } + fn last(&self) -> i32 { + self.1 + } } //必须显示声明所有泛型 - fn difference(container: &C) -> i32 where - C: Contains { + fn difference(container: &C) -> i32 + where + C: Contains, + { container.last() - container.first() } let number_1 = 3; let number_2 = 10; let container = Container(number_1, number_2); - println!("Does container contain {} and {}: {}", &number_1, &number_2, container.contains(&number_1, &number_2)); + println!( + "Does container contain {} and {}: {}", + &number_1, + &number_2, + container.contains(&number_1, &number_2) + ); println!("First number: {}", container.first()); println!("Last number: {}", container.last()); println!("The difference is: {}", difference(&container)); @@ -235,8 +269,12 @@ fn associated_types() { fn contains(&self, number_1: &i32, number_2: &i32) -> bool { (&self.0 == number_1) && (&self.1 == number_2) } - fn first(&self) -> i32 { self.0 } - fn last(&self) -> i32 { self.1 } + fn first(&self) -> i32 { + self.0 + } + fn last(&self) -> i32 { + self.1 + } } //使用关联类型后定义更加简洁 fn difference(container: &C) -> i32 { @@ -245,7 +283,12 @@ fn associated_types() { let number_1 = 3; let number_2 = 10; let container = Container(number_1, number_2); - println!("Does container contain {} and {}: {}", &number_1, &number_2, container.contains(&number_1, &number_2)); + println!( + "Does container contain {} and {}: {}", + &number_1, + &number_2, + container.contains(&number_1, &number_2) + ); println!("First number: {}", container.first()); println!("Last number: {}", container.last()); println!("The difference is: {}", difference(&container)); @@ -259,8 +302,8 @@ fn associated_types() { //标记拥有关系; //自动trait实现(send/sync); fn phantom_type_parameters() { - use std::ops::Add; use std::marker::PhantomData; + use std::ops::Add; #[derive(Debug, Clone, Copy)] enum Inch {} #[derive(Debug, Clone, Copy)] @@ -287,4 +330,4 @@ fn phantom_type_parameters() { println!("one foot + one_foot = {:?} in", two_feet.0); println!("one meter + one_meter = {:?} mm", two_meters.0); //let one_feter = one_foot + one_meter;//error 2个相加的类型的泛型不同 -} \ No newline at end of file +} diff --git a/rust-examples/src/main.rs b/rust-examples/src/main.rs index 3457a27f..5bf23589 100644 --- a/rust-examples/src/main.rs +++ b/rust-examples/src/main.rs @@ -15,18 +15,18 @@ use crate::traits::*; use crate::types::*; use crate::variable_bindings::*; +pub mod closures; +pub mod conversion; +pub mod custom_types; +pub mod flow_control; pub mod formatted_print; -pub mod misc; -pub mod traits; +pub mod functions; pub mod generics; +pub mod misc; pub mod modules; -pub mod functions; -pub mod flow_control; -pub mod closures; -pub mod conversion; -pub mod types; pub mod primitives; -pub mod custom_types; +pub mod traits; +pub mod types; pub mod variable_bindings; ///为了方便将每个知识点分为单独的源文件,并提供与之相同的公开方法测试内部所有代码 diff --git a/rust-examples/src/misc.rs b/rust-examples/src/misc.rs index d00422b0..e22fe817 100644 --- a/rust-examples/src/misc.rs +++ b/rust-examples/src/misc.rs @@ -32,7 +32,7 @@ fn threads() { for child in children { //等待线程完成,返回结果。_ 匿名变量,不需要这个结果 - let _ = child.join();//按顺序从0~9打印 + let _ = child.join(); //按顺序从0~9打印 } } @@ -63,14 +63,16 @@ fn thread_testcase() { // TODO: try removing the 'move' and see what happens children.push(thread::spawn(move || -> u32 { //转化为数字并计算此段的中间和 - let result = data_segment.chars().map(|c| c.to_digit(10).expect("should be a digit")).sum(); + let result = data_segment + .chars() + .map(|c| c.to_digit(10).expect("should be a digit")) + .sum(); println!("processed segment {}, result={}", i, result); //每个子线程都返回中间结果 result })); } - //将每个线程的中间结果收集到一个新的Vec中 let mut intermediate_sums = vec![]; for child in children { @@ -87,8 +89,8 @@ fn thread_testcase() { //通道 fn channels() { - use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; + use std::sync::mpsc::{Receiver, Sender}; use std::thread; static NTHREADS: i32 = 3; @@ -210,7 +212,10 @@ fn file_read_lines() { } } - fn read_lines

(filename: P) -> io::Result>> where P: AsRef, { + fn read_lines

(filename: P) -> io::Result>> + where + P: AsRef, + { let file = File::open(filename)?; //返回文件上的迭代器 Ok(io::BufReader::new(file).lines()) @@ -221,9 +226,10 @@ fn file_read_lines() { fn child_processes() { use std::process::Command; - let output = Command::new("rustc").arg("--version").output().unwrap_or_else(|e| { - panic!("failed to execute process: {}", e) - }); + let output = Command::new("rustc") + .arg("--version") + .output() + .unwrap_or_else(|e| panic!("failed to execute process: {}", e)); if output.status.success() { let s = String::from_utf8_lossy(&output.stdout); @@ -246,7 +252,8 @@ fn child_processes_pipes() { let process = match Command::new("wc") .stdin(Stdio::piped()) .stdout(Stdio::piped()) - .spawn() { + .spawn() + { Err(why) => panic!("couldn't spawn wc: {}", why.description()), Ok(process) => process, }; @@ -350,9 +357,11 @@ fn filesystem_operations() { // Read the contents of a directory, returns `io::Result>` match fs::read_dir("a") { Err(why) => println!("! {:?}", why.kind()), - Ok(paths) => for path in paths { - println!("> {:?}", path.unwrap().path()); - }, + Ok(paths) => { + for path in paths { + println!("> {:?}", path.unwrap().path()); + } + } } println!("`rm a/c/e.txt`"); @@ -393,11 +402,13 @@ fn argument_parsing() { } fn help() { - println!("usage: + println!( + "usage: match_args Check whether given string is the answer. match_args {{increase|decrease}} - Increase or decrease given integer by one."); + Increase or decrease given integer by one." + ); } let args: Vec = env::args().collect(); @@ -405,20 +416,16 @@ match_args {{increase|decrease}} 1 => { println!("My name is 'match_args'. Try passing some arguments!"); } - 2 => { - match args[1].parse() { - Ok(42) => println!("This is the answer!"), - _ => println!("This is not the answer."), - } - } + 2 => match args[1].parse() { + Ok(42) => println!("This is the answer!"), + _ => println!("This is not the answer."), + }, 3 => { let cmd = &args[1]; let num = &args[2]; // parse the number let number: i32 = match num.parse() { - Ok(n) => { - n - } + Ok(n) => n, Err(_) => { eprintln!("error: second argument not an integer"); help(); @@ -446,7 +453,7 @@ fn foreign_function_interface() { //这个外部块链接到libm库 #[link(name = "m")] - extern { + extern "C" { fn csqrtf(z: Complex) -> Complex; fn ccosf(z: Complex) -> Complex; @@ -483,4 +490,4 @@ fn foreign_function_interface() { println!("the square root of {:?} is {:?}", z, z_sqrt); println!("cos({:?}) = {:?}", z, cos(z)); -} \ No newline at end of file +} diff --git a/rust-examples/src/modules.rs b/rust-examples/src/modules.rs index 0635b25e..98fcbf82 100644 --- a/rust-examples/src/modules.rs +++ b/rust-examples/src/modules.rs @@ -12,7 +12,7 @@ fn struct_visibility() { } //公有结构体和私有字段 - #[allow(dead_code)]//禁用编译器的 未使用警告 + #[allow(dead_code)] //禁用编译器的 未使用警告 pub struct ClosedBox { contents: T, } @@ -20,14 +20,14 @@ fn struct_visibility() { impl ClosedBox { //公有的构造函数 pub fn new(contents: T) -> ClosedBox { - ClosedBox { - contents: contents, - } + ClosedBox { contents: contents } } } } - let open_box = my::OpenBox { contents: "public information" }; + let open_box = my::OpenBox { + contents: "public information", + }; println!("The open box contains: {}", open_box.contents); //ERROR @@ -67,9 +67,10 @@ fn cfg() { are_you_on_linux2(); println!("Are you sure?"); - if cfg!(target_os = "linux") {//target_os由rustc隐式提供,但是自定义条件条件必须使用--cfg标志传递给rustc + if cfg!(target_os = "linux") { + //target_os由rustc隐式提供,但是自定义条件条件必须使用--cfg标志传递给rustc println!("Yes. It's definitely linux!"); } else { println!("Yes. It's definitely *not* linux!"); } -} \ No newline at end of file +} diff --git a/rust-examples/src/primitives.rs b/rust-examples/src/primitives.rs index 0786cc3a..a1b4e936 100644 --- a/rust-examples/src/primitives.rs +++ b/rust-examples/src/primitives.rs @@ -17,7 +17,9 @@ fn tuples() { struct Matrix(f32, f32, f32, f32); //一组不同类型的元组 - let long_tuple = (1u8, 2u16, 3u32, 4u64, -1i8, -2i16, -3i32, -4i64, 0.1f32, 0.2f64, 'a', true); + let long_tuple = ( + 1u8, 2u16, 3u32, 4u64, -1i8, -2i16, -3i32, -4i64, 0.1f32, 0.2f64, 'a', true, + ); //可以使用元组索引从元组中提取值 println!("long tuple first value: {}", long_tuple.0); @@ -41,7 +43,7 @@ fn tuples() { //要创建含有一个元素的元组,需要逗号来区分它们 // from a literal surrounded by parentheses - println!("one element tuple: {:?}", (5u32, )); + println!("one element tuple: {:?}", (5u32,)); println!("just an integer: {:?}", (5u32)); //元组可以被解构以创建绑定 @@ -89,4 +91,4 @@ fn arrays_and_slices() { //索引越界导致编译错误 //println!("{}", xs[5]); -} \ No newline at end of file +} diff --git a/rust-examples/src/traits.rs b/rust-examples/src/traits.rs index 48ddd350..a968fb50 100644 --- a/rust-examples/src/traits.rs +++ b/rust-examples/src/traits.rs @@ -1,6 +1,9 @@ ///特质 pub fn traits() { - struct Sheep { naked: bool, name: &'static str } + struct Sheep { + naked: bool, + name: &'static str, + } impl Sheep { fn is_naked(&self) -> bool { @@ -36,7 +39,10 @@ pub fn traits() { impl Animal for Sheep { //self的类型是`Sheep` fn new(name: &'static str) -> Sheep { - Sheep { name: name, naked: false } + Sheep { + name: name, + naked: false, + } } fn name(&self) -> &'static str { @@ -65,7 +71,6 @@ pub fn traits() { dolly.shear(); dolly.talk(); - // derive(); return_dyn(); @@ -79,7 +84,6 @@ pub fn traits() { overlapping_traits(); } - fn derive() { //比较特质: Eq, PartialEq, Ord, PartialOrd. //拷贝特质(深拷贝), to create T from &T via a copy. @@ -118,12 +122,11 @@ fn derive() { let meter = Centimeters(100.0); - let cmp = - if foot.to_centimeters() < meter { - "smaller" - } else { - "bigger" - }; + let cmp = if foot.to_centimeters() < meter { + "smaller" + } else { + "bigger" + }; println!("One foot is {} than one meter.", cmp); } @@ -163,7 +166,10 @@ fn return_dyn() { let random_number = 0.234; let animal = random_animal(random_number); - println!("You've randomly chosen an animal, and it says {}", animal.noise()); + println!( + "You've randomly chosen an animal, and it says {}", + animal.noise() + ); } fn operator_overload() { @@ -306,12 +312,15 @@ fn impl_trait() { use std::vec::IntoIter; //组合vec - fn combine_vecs_explicit_return_type(v: Vec, u: Vec) -> iter::Cycle, IntoIter>> { + fn combine_vecs_explicit_return_type( + v: Vec, + u: Vec, + ) -> iter::Cycle, IntoIter>> { v.into_iter().chain(u.into_iter()).cycle() } //简化返回类型 - fn combine_vecs(v: Vec, u: Vec) -> impl Iterator { + fn combine_vecs(v: Vec, u: Vec) -> impl Iterator { v.into_iter().chain(u.into_iter()).cycle() } @@ -328,14 +337,14 @@ fn impl_trait() { fn closure_trait() { fn make_adder_function(y: i32) -> impl Fn(i32) -> i32 { - let closure = move |x: i32| { x + y }; + let closure = move |x: i32| x + y; closure } let plus_one = make_adder_function(1); assert_eq!(plus_one(2), 3); - fn double_positives<'a>(numbers: &'a Vec) -> impl Iterator + 'a { + fn double_positives<'a>(numbers: &'a Vec) -> impl Iterator + 'a { numbers.iter().filter(|x| x > &&0).map(|x| x * 2) } } @@ -443,4 +452,4 @@ fn overlapping_traits() { let age =

::get(&form); assert_eq!(28, age); -} \ No newline at end of file +} diff --git a/rust-examples/src/types.rs b/rust-examples/src/types.rs index 3c748de0..a3738a47 100644 --- a/rust-examples/src/types.rs +++ b/rust-examples/src/types.rs @@ -46,4 +46,4 @@ fn literals() { println!("size of `z` in bytes: {}", std::mem::size_of_val(&z)); println!("size of `i` in bytes: {}", std::mem::size_of_val(&i)); println!("size of `f` in bytes: {}", std::mem::size_of_val(&f)); -} \ No newline at end of file +} diff --git a/rust-examples/src/variable_bindings.rs b/rust-examples/src/variable_bindings.rs index 04a290af..3a15ea3a 100644 --- a/rust-examples/src/variable_bindings.rs +++ b/rust-examples/src/variable_bindings.rs @@ -17,7 +17,6 @@ pub fn variable_bindings() { let noisy_unused_variable = 2u32; - //可变 let _immutable_binding = 1; let mut mutable_binding = 1; @@ -78,4 +77,4 @@ fn declare_first() { another_binding = 1; println!("another binding: {}", another_binding); -} \ No newline at end of file +} diff --git a/rust-exercise/src/closures_syntax.rs b/rust-exercise/src/closures_syntax.rs index a617b202..19bdc5fa 100644 --- a/rust-exercise/src/closures_syntax.rs +++ b/rust-exercise/src/closures_syntax.rs @@ -13,11 +13,7 @@ pub fn closures_syntax() { let simulated_user_specified_value = 10; let simulated_random_number = 7; - generate_workout4( - simulated_user_specified_value, - simulated_random_number, - ); - + generate_workout4(simulated_user_specified_value, simulated_random_number); ///初始版本 fn generate_workout(intensity: u32, random_number: u32) { @@ -44,26 +40,16 @@ pub fn closures_syntax() { ///将调研提取到一个地方,存储在expensive_result变量中 fn generate_workout2(intensity: u32, random_number: u32) { - let expensive_result = - simulated_expensive_calculation(intensity); + let expensive_result = simulated_expensive_calculation(intensity); if intensity < 25 { - println!( - "Today, do {} pushups!", - expensive_result - ); - println!( - "Next, do {} situps!", - expensive_result - ); + println!("Today, do {} pushups!", expensive_result); + println!("Next, do {} situps!", expensive_result); } else { if random_number == 3 { println!("Take a break today! Remember to stay hydrated!"); } else { - println!( - "Today, run for {} minutes!", - expensive_result - ); + println!("Today, run for {} minutes!", expensive_result); } } } @@ -71,29 +57,21 @@ pub fn closures_syntax() { ///使用闭包重构以存储代码 fn generate_workout3(intensity: u32, random_number: u32) { ///定义一个闭包并将其存储在 expensive_closure变量中 - let expensive_closure = |num| {//如果我们有多个参数,则将它们用逗号分隔,例如|param1, param2|,显示定义类型:|num: u32| -> u32 + let expensive_closure = |num| { + //如果我们有多个参数,则将它们用逗号分隔,例如|param1, param2|,显示定义类型:|num: u32| -> u32 println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); num }; if intensity < 25 { - println!( - "Today, do {} pushups!", - expensive_closure(intensity) - ); - println!( - "Next, do {} situps!", - expensive_closure(intensity) - ); + println!("Today, do {} pushups!", expensive_closure(intensity)); + println!("Next, do {} situps!", expensive_closure(intensity)); } else { if random_number == 3 { println!("Take a break today! Remember to stay hydrated!"); } else { - println!( - "Today, run for {} minutes!", - expensive_closure(intensity) - ); + println!("Today, run for {} minutes!", expensive_closure(intensity)); } } } @@ -106,14 +84,8 @@ pub fn closures_syntax() { num }); if intensity < 25 { - println!( - "Today, do {} pushups!", - expensive_result.value(intensity) - ); - println!( - "Next, do {} situps!", - expensive_result.value(intensity) - ); + println!("Today, do {} pushups!", expensive_result.value(intensity)); + println!("Next, do {} situps!", expensive_result.value(intensity)); } else { if random_number == 3 { println!("Take a break today! Remember to stay hydrated!"); @@ -126,10 +98,12 @@ pub fn closures_syntax() { } } - fn add_one_v1(x: u32) -> u32 { x + 1 }//显示函数定义 - let add_one_v2 = |x: u32| -> u32 { x + 1 };//完整注释的闭包定义 - let add_one_v3 = |x: u32| { x + 1 };//删除类型,没有使用该闭包时不加u32会报错 - let add_one_v4 = |x: u32| x + 1;//删除括号,没有使用该闭包时不加u32会报错 + fn add_one_v1(x: u32) -> u32 { + x + 1 + } //显示函数定义 + let add_one_v2 = |x: u32| -> u32 { x + 1 }; //完整注释的闭包定义 + let add_one_v3 = |x: u32| x + 1; //删除类型,没有使用该闭包时不加u32会报错 + let add_one_v4 = |x: u32| x + 1; //删除括号,没有使用该闭包时不加u32会报错 ///两次使用闭包传入了不同类型参数,将会报错 ///如果尝试对同一闭包使用其他不同类型,则会收到类型错误。 @@ -152,14 +126,19 @@ pub fn closures_syntax() { } ///定义一个包含闭包的结构,闭包类型Fn(u32) -> u32 -struct Cacher where T: Fn(u32) -> u32 { +struct Cacher +where + T: Fn(u32) -> u32, +{ calculation: T, value: Option, } - ///实现结构 -impl Cacher where T: Fn(u32) -> u32 { +impl Cacher +where + T: Fn(u32) -> u32, +{ fn new(calculation: T) -> Cacher { //没有执行时默认是None Cacher { @@ -191,5 +170,5 @@ fn call_with_different_values() { //失败 let v2 = c.value(2); - assert_ne!(v2, 2);//不等!!!! -} \ No newline at end of file + assert_ne!(v2, 2); //不等!!!! +} diff --git a/rust-exercise/src/collection_function.rs b/rust-exercise/src/collection_function.rs index 0d32f913..90f2412b 100644 --- a/rust-exercise/src/collection_function.rs +++ b/rust-exercise/src/collection_function.rs @@ -3,38 +3,37 @@ use std::string::ToString; ///https://doc.rust-lang.org/stable/nomicon/vec.html. ///集合 pub fn collection_function() { - let mut v: Vec = Vec::new();//Vec类似ArrayList,称为向量? - v.push(12);//想要修改必须定义为mut可变的 + let mut v: Vec = Vec::new(); //Vec类似ArrayList,称为向量? + v.push(12); //想要修改必须定义为mut可变的 println!("{:#?}", v); let v = vec![1, 2, 3]; println!("{:#?}", v); let v = vec![1, 2, 3, 4, 5]; - let third = &v[2];//获取元素 + let third = &v[2]; //获取元素 println!("The third element is {}", third); match v.get(2) { Some(third) => println!("The third element is {}", third), None => println!("There is no third element."), } - //let does_not_exist = &v[100];//恐慌,编译时直接退出程序 ///当将get方法传递给向量之外的索引时,它将返回None且不会出现惊慌。如果在正常情况下偶尔访问超出向量范围的元素,则可以使用此方法。 ///您的代码将需要具有处理Some(&element)或None的逻辑, let does_not_exist = v.get(100); ///当程序具有有效的引用时,借位检查器将执行所有权和借用规则 let mut v = vec![1, 2, 3, 4, 5]; - let first = v[0];//使用引用&v[0]将会报错 - v.push(6);//尝试保留第一个元素的引用的同时向向量添加元素将会出现编译错误,此时引用可能改变 + let first = v[0]; //使用引用&v[0]将会报错 + v.push(6); //尝试保留第一个元素的引用的同时向向量添加元素将会出现编译错误,此时引用可能改变 println!("The first element is: {}", first); ///遍历向量集合 let v = vec![100, 32, 57]; for i in &v { - println!("{}", i);//直接打印 i,而不需要使用c语言中的*i,省略了* + println!("{}", i); //直接打印 i,而不需要使用c语言中的*i,省略了* } let mut v = vec![100, 32, 57]; for i in &mut v { - *i += 50;//对可变的向量进行操作,让每个元素都增加50 + *i += 50; //对可变的向量进行操作,让每个元素都增加50 println!("{}", i) } @@ -65,7 +64,7 @@ pub fn collection_function() { println!("{}", s); let s = "initial contents".to_string(); println!("{}", s); - let s = String::from("initial contents");//从字符串文字(字符串常量 切片 &str类型)创建字符串(对象/String类型) + let s = String::from("initial contents"); //从字符串文字(字符串常量 切片 &str类型)创建字符串(对象/String类型) println!("{}", s); //其他编码的文字 let hello = String::from("السلام عليكم"); @@ -86,16 +85,16 @@ pub fn collection_function() { let mut s1 = String::from("foo"); let s2 = "bar"; s1.push_str(s2); - println!("s2 is {}", s2);//s2被加到s1之后,再次使用s2 + println!("s2 is {}", s2); //s2被加到s1之后,再次使用s2 let mut s = String::from("lo"); - s.push('l');//使用push向字符串值添加一个字符 + s.push('l'); //使用push向字符串值添加一个字符 ///合并字符串 let s1 = String::from("Hello, "); let s2 = String::from("world!"); let s3 = s1 + &s2; //s1被移动,之后无法再次使用 - //+ 方法 使用add方法 fn add(self, s: &str) -> String { - //所以+组合字符串第二个参数必须是 &str的,但是这是因为编译器将&String转化为&str了。 + //+ 方法 使用add方法 fn add(self, s: &str) -> String { + //所以+组合字符串第二个参数必须是 &str的,但是这是因为编译器将&String转化为&str了。 let s1 = String::from("tic"); let s2 = String::from("tac"); let s3 = String::from("toe"); @@ -124,10 +123,10 @@ pub fn collection_function() { ///但是用String不能保证性能,因为Rust必须从头到尾遍历所有内容以确定有多少个有效字符。 ///有效的Unicode标量值可能由1个以上的字节组成,从rust字符串中获取字素簇很复杂,标准库并未提供此功能 for c in "नमस्ते".chars() { - println!("{}", c);//न म स ् त े ,一个字符由2个char组成 + println!("{}", c); //न म स ् त े ,一个字符由2个char组成 } for b in "नमस्ते".bytes() { - println!("{}", b);//返回字节,很多个 + println!("{}", b); //返回字节,很多个 } ///hash map @@ -144,7 +143,7 @@ pub fn collection_function() { let field_name = String::from("Favorite color"); let field_value = String::from("Blue"); let mut map = HashMap::new(); - map.insert(field_name, field_value);//此时field_name和field_value无效,已经被移动到map中 + map.insert(field_name, field_value); //此时field_name和field_value无效,已经被移动到map中 ///获取key对应的value let team_name = String::from("Blue"); let score = scores.get(&team_name); @@ -164,4 +163,4 @@ pub fn collection_function() { } println!("{:?}", map); -}//v超出范围并在此处释放 +} //v超出范围并在此处释放 diff --git a/rust-exercise/src/control_function.rs b/rust-exercise/src/control_function.rs index 1c775d24..cefcc4f1 100644 --- a/rust-exercise/src/control_function.rs +++ b/rust-exercise/src/control_function.rs @@ -9,7 +9,7 @@ pub fn control_function() { } ///处理多个if - let number = 6;//阴影,遮盖了前面的number + let number = 6; //阴影,遮盖了前面的number if number % 4 == 0 { println!("number is divisible by 4"); @@ -24,18 +24,14 @@ pub fn control_function() { ///与Scala一样,可以将if表达式的结果赋值给变量(这里的变量一般是指不可变的变量,虽然绕口,但是确实是事实) let condition = true; ///从每个分支取得的if的返回值必须是同一类型,否则编译报错 - let number = if condition { - 5 - } else { - 6 - }; + let number = if condition { 5 } else { 6 }; println!("The value of number is: {}", number); ///循环 loop { println!("again!"); - break;//这个分号可省 + break; //这个分号可省 } ///从循环中返回值 let mut counter = 0; @@ -44,7 +40,7 @@ pub fn control_function() { counter += 1; if counter == 10 { break counter * 2; - };//这个分号可省 + }; //这个分号可省 }; ///分号的使用还不清晰明确,后面再看 @@ -57,7 +53,7 @@ pub fn control_function() { while number != 0 { println!("{}!", number); number -= 1; - };//这个分号可以省略 + } //这个分号可以省略 println!("LIFTOFF!!!"); ///while变量数组 @@ -83,4 +79,4 @@ pub fn control_function() { print!("{}!", number); } println!("LIFTOFF!!!"); -} \ No newline at end of file +} diff --git a/rust-exercise/src/enum_data_type.rs b/rust-exercise/src/enum_data_type.rs index 32c24c50..855b8603 100644 --- a/rust-exercise/src/enum_data_type.rs +++ b/rust-exercise/src/enum_data_type.rs @@ -31,7 +31,6 @@ pub fn enum_data_type() { address: String::from("::1"), }; - ///数值直接放入每个枚举变量中,而不是需要使用结构体 struct IpAddr enum IpAddr2 { V4(String), diff --git a/rust-exercise/src/example_guessing_game.rs b/rust-exercise/src/example_guessing_game.rs index d31547bf..62de233d 100644 --- a/rust-exercise/src/example_guessing_game.rs +++ b/rust-exercise/src/example_guessing_game.rs @@ -15,12 +15,14 @@ pub fn example_guessing_game() { println!("Please input your guess."); //变量默认是不可变的。使用mut表示变量是可变的,定义成let foo = 5; 则是不可变。 - let mut guess = String::new();//关联函数,在类型上实现。一些语言称为静态方法。该函数创建了一个空串 + let mut guess = String::new(); //关联函数,在类型上实现。一些语言称为静态方法。该函数创建了一个空串 //没有使用use,则这里需要写成 std::io::stdin //&表示该参数是一个引用,Rust的主要优势之一是使用引用的安全性和便捷性 //&使您代码的多个部分可以访问同一条数据,而无需将该数据多次复制到内存中 - io::stdin().read_line(&mut guess).expect("Failed to read line"); + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); //无法比较数值与字符串需要转化为数值,Rust默认为i32 //Rust允许我们用新的值遮盖以前的值guess。此功能通常用于要将值从一种类型转换为另一种类型的情况。 @@ -48,4 +50,4 @@ pub fn example_guessing_game() { } } } -} \ No newline at end of file +} diff --git a/rust-exercise/src/front_of_house.rs b/rust-exercise/src/front_of_house.rs index 2d6c779f..ccd3340d 100644 --- a/rust-exercise/src/front_of_house.rs +++ b/rust-exercise/src/front_of_house.rs @@ -4,4 +4,4 @@ pub mod hosting; //Rust会查找 src/hosting.rs(同名文件) 或者 src/hosting/mod.rs,mod不再包含子模块则使用src/hosting.rs,否则使用src/hosting/mod.rs pub fn add_to_waitlist() { hosting::add_to_waitlist_host(); -} \ No newline at end of file +} diff --git a/rust-exercise/src/front_of_house/hosting.rs b/rust-exercise/src/front_of_house/hosting.rs index 44b5a7fb..a6272994 100644 --- a/rust-exercise/src/front_of_house/hosting.rs +++ b/rust-exercise/src/front_of_house/hosting.rs @@ -1,4 +1,4 @@ //hosting是front_of_house的子模块,hosting在front_of_house的文件夹里面,使用fn公开方法 pub fn add_to_waitlist_host() { println!("hello world aaaaaaaaaaaa") -} \ No newline at end of file +} diff --git a/rust-exercise/src/generic_traits_lifetimes.rs b/rust-exercise/src/generic_traits_lifetimes.rs index 051d75e0..33737c0a 100644 --- a/rust-exercise/src/generic_traits_lifetimes.rs +++ b/rust-exercise/src/generic_traits_lifetimes.rs @@ -2,7 +2,6 @@ use std::fmt::{Debug, Display}; ///通用类型,特征和寿命 - pub fn largest_function() { //在数字列表中查找最大数字的代码 let number_list = vec![34, 50, 25, 100, 65]; @@ -200,9 +199,17 @@ pub fn trait_function() { } ///这样写太麻烦 - fn some_function(t: T, u: U) -> i32 { 1 } + fn some_function(t: T, u: U) -> i32 { + 1 + } //简化 - fn some_function2(t: T, u: U) -> i32 where T: Display + Clone, U: Clone + Debug { 1 } + fn some_function2(t: T, u: U) -> i32 + where + T: Display + Clone, + U: Clone + Debug, + { + 1 + } ///返回实现特征的类型 fn returns_summarizable() -> impl Summary { @@ -215,24 +222,24 @@ pub fn trait_function() { } //下面是无效的,编译不过 //由于在编译器中实现impl Trait语法方面的限制,因此不允许返回NewsArticle或Tweet -// fn returns_summarizable2(switch: bool) -> impl Summary { -// if switch { -// NewsArticle { -// headline: String::from("Penguins win the Stanley Cup Championship!"), -// location: String::from("Pittsburgh, PA, USA"), -// author: String::from("Iceburgh"), -// content: String::from("The Pittsburgh Penguins once again are the best -// hockey team in the NHL."), -// } -// } else { -// Tweet { -// username: String::from("horse_ebooks"), -// content: String::from("of course, as you probably already know, people"), -// reply: false, -// retweet: false, -// } -// } -// } + // fn returns_summarizable2(switch: bool) -> impl Summary { + // if switch { + // NewsArticle { + // headline: String::from("Penguins win the Stanley Cup Championship!"), + // location: String::from("Pittsburgh, PA, USA"), + // author: String::from("Iceburgh"), + // content: String::from("The Pittsburgh Penguins once again are the best + // hockey team in the NHL."), + // } + // } else { + // Tweet { + // username: String::from("horse_ebooks"), + // content: String::from("of course, as you probably already know, people"), + // reply: false, + // retweet: false, + // } + // } + // } struct Pair { x: T, @@ -240,10 +247,7 @@ pub fn trait_function() { } impl Pair { fn new(x: T, y: T) -> Self { - Self { - x, - y, - } + Self { x, y } } } ///始终实现new函数,但是Pair仅在内部类型T实现了实现比较的PartialOrd特质和实现打印的Display特质的情况下,才实现cmp_display方法。 @@ -261,38 +265,38 @@ pub fn trait_function() { ///生命周期 fn lifetimes_function() { -//使用生命周期验证引用 -//在大多数情况下,生存期是隐式和推断的,就像在大多数情况下一样,推断类型。 -//当可能有多个类型时,必须注释类型。以类似的方式,当引用的生存期可以通过几种不同方式关联时,我们必须注释生存期。 -//Rust要求我们使用通用生命周期参数注释关系,以确保在运行时使用的实际引用绝对有效。 -//生命周期的主要目的是防止引用悬而未决,从而导致程序引用的数据不是其要引用的数据。 -// { -// r和x的生命周期注释,分别命名为'a和'b -// let r; // ---------+-- 'a - // | -// { // | -// let x = 5; // -+-- 'b | -// r = &x; // | | -// } // -+ | - // | -// println!("r: {}", r); // | -// } // ----------+ + //使用生命周期验证引用 + //在大多数情况下,生存期是隐式和推断的,就像在大多数情况下一样,推断类型。 + //当可能有多个类型时,必须注释类型。以类似的方式,当引用的生存期可以通过几种不同方式关联时,我们必须注释生存期。 + //Rust要求我们使用通用生命周期参数注释关系,以确保在运行时使用的实际引用绝对有效。 + //生命周期的主要目的是防止引用悬而未决,从而导致程序引用的数据不是其要引用的数据。 + // { + // r和x的生命周期注释,分别命名为'a和'b + // let r; // ---------+-- 'a + // | + // { // | + // let x = 5; // -+-- 'b | + // r = &x; // | | + // } // -+ | + // | + // println!("r: {}", r); // | + // } // ----------+ ///正确代码 { - let x = 5; // ----------+-- 'b - // | - let r = &x; // --+-- 'a | - // | | + let x = 5; // ----------+-- 'b + // | + let r = &x; // --+-- 'a | + // | | println!("r: {}", r); // | | // --+ | - } // ----------+ + } // ----------+ ///函数的通用生命周期 ///过于复杂,建议有时间再研究:https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html -// &i32 // 一个引用 -// &'a i32 // 具有明确生命周期的引用 -// &'a mut i32 // 具有显式寿命的可变引用 + // &i32 // 一个引用 + // &'a i32 // 具有明确生命周期的引用 + // &'a mut i32 // 具有显式寿命的可变引用 ///指定签名中的所有引用必须具有相同的生存期 'a fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { @@ -302,5 +306,3 @@ fn lifetimes_function() { } } } - - diff --git a/rust-exercise/src/iterator_demonstration.rs b/rust-exercise/src/iterator_demonstration.rs index 41f0dd3a..f89eac61 100644 --- a/rust-exercise/src/iterator_demonstration.rs +++ b/rust-exercise/src/iterator_demonstration.rs @@ -7,7 +7,6 @@ pub fn iterator_function() { println!("{}", v2 == vec![2, 3, 4]) } - struct Counter { count: u32, } @@ -42,7 +41,6 @@ fn calling_next_directly() { assert_eq!(counter.next(), None); } - #[derive(PartialEq, Debug)] struct Shoe { size: u32, @@ -57,21 +55,35 @@ fn shoes_in_my_size(shoes: Vec, shoe_size: u32) -> Vec { #[test] fn filters_by_size() { let shoes = vec![ - Shoe { size: 10, style: String::from("sneaker") }, - Shoe { size: 13, style: String::from("sandal") }, - Shoe { size: 10, style: String::from("boot") }, + Shoe { + size: 10, + style: String::from("sneaker"), + }, + Shoe { + size: 13, + style: String::from("sandal"), + }, + Shoe { + size: 10, + style: String::from("boot"), + }, ]; let in_my_size = shoes_in_my_size(shoes, 10); assert_eq!( in_my_size, vec![ - Shoe { size: 10, style: String::from("sneaker") }, - Shoe { size: 10, style: String::from("boot") }, + Shoe { + size: 10, + style: String::from("sneaker") + }, + Shoe { + size: 10, + style: String::from("boot") + }, ] ); } - #[test] fn iterator_demonstration() { let v1 = vec![1, 2, 3]; @@ -93,9 +105,10 @@ fn iterator_sum() { #[test] fn using_other_iterator_trait_methods() { - let sum: u32 = Counter::new().zip(Counter::new().skip(1)) + let sum: u32 = Counter::new() + .zip(Counter::new().skip(1)) .map(|(a, b)| a * b) .filter(|x| x % 3 == 0) .sum(); assert_eq!(18, sum); -} \ No newline at end of file +} diff --git a/rust-exercise/src/lib.rs b/rust-exercise/src/lib.rs index 21db7957..b5a901f3 100644 --- a/rust-exercise/src/lib.rs +++ b/rust-exercise/src/lib.rs @@ -32,7 +32,7 @@ pub mod front_of_house; //使用 pub公开模块的功能 pub fn eat_at_restaurant() { // 使用绝对路径,更好 -// crate::front_of_house::hosting::add_to_waitlist_host(); + // crate::front_of_house::hosting::add_to_waitlist_host(); // 使用相对路径 front_of_house::hosting::add_to_waitlist_host(); } @@ -52,7 +52,7 @@ mod back_of_house { pub struct Breakfast { pub toast: String, //该结构是公开的,且只有toast是公开的属性字段 - seasonal_fruit: String,//无法更改 + seasonal_fruit: String, //无法更改 } impl Breakfast { @@ -72,14 +72,13 @@ mod back_of_house { } } - //mod front_of_house;//在mod front_of_house之后使用分号(而不是使用块)会告诉Rust从另一个与模块同名的文件中加载模块的内容。 //pub use 重新导出,使名称可用于新范围内的任何代码 (因为我们将一个项目放入范围内,同时也使该项目可供其他人进入其范围) //use std::collections::*; //导入所有内部的类型 pub fn eat_at_restaurant2() { - let mut meal = back_of_house::Breakfast::summer("Rye");//关联函数 summer 用于构造实例 + let mut meal = back_of_house::Breakfast::summer("Rye"); //关联函数 summer 用于构造实例 meal.toast = String::from("Wheat"); println!("I'd like {} toast please", meal.toast); //下面编译不过,seasonal_fruit是私有的 @@ -89,12 +88,12 @@ pub fn eat_at_restaurant2() { let order2 = back_of_house::Appetizer::Salad; //使用use导入模块,可以省略模块前缀,使代码简洁 - front_of_house::hosting::add_to_waitlist_host();//front_of_house :: hosting 二级包 + front_of_house::hosting::add_to_waitlist_host(); //front_of_house :: hosting 二级包 front_of_house::hosting::add_to_waitlist_host(); front_of_house::hosting::add_to_waitlist_host(); //use的习惯用法,但是不同模块中的相同函数,需要加模块前缀,如:fmt::Result,io::Result - use std::collections::HashMap as RustHashMap;//使用as为导入的类型提供别名,一般在最前面使用导入,这里为了方便 + use std::collections::HashMap as RustHashMap; //使用as为导入的类型提供别名,一般在最前面使用导入,这里为了方便 let mut map = RustHashMap::new(); map.insert(1, 2); -} \ No newline at end of file +} diff --git a/rust-exercise/src/macro_syntax.rs b/rust-exercise/src/macro_syntax.rs index 128379c9..91cdf09a 100644 --- a/rust-exercise/src/macro_syntax.rs +++ b/rust-exercise/src/macro_syntax.rs @@ -14,7 +14,7 @@ ///} /// /// -#[macro_export]//#[macro_export]注解(注释)表示,只要将定义了该宏的板条箱放入范围内,就应使该宏可用。没有此注释,宏将无法进入范围。 +#[macro_export] //#[macro_export]注解(注释)表示,只要将定义了该宏的板条箱放入范围内,就应使该宏可用。没有此注释,宏将无法进入范围。 macro_rules! Vec {//然后,我们从macro_rules! 开始宏定义!以及我们定义的不带感叹号的宏的名称。该名称(在本例中为Vec)后跟大括号,表示宏定义的正文。 ( $( $x:expr ),* ) => {//模式与代码块,宏模式是针对Rust代码结构而非值进行匹配的 //首先一组括号()包括整个模式,这些括号捕获与括号内的模式匹配的值,以供替换代码使用 @@ -33,6 +33,6 @@ macro_rules! Vec {//然后,我们从macro_rules! 开始宏定义!以及我 pub fn marco_function() { ///定义自己的宏。(标准库的是vec!) - let v: Vec = Vec![1, 2, 3];// $x 匹配 1,2,3 三次 - println!("{}", v.len())//宏定义必须在前面 -} \ No newline at end of file + let v: Vec = Vec![1, 2, 3]; // $x 匹配 1,2,3 三次 + println!("{}", v.len()) //宏定义必须在前面 +} diff --git a/rust-exercise/src/main.rs b/rust-exercise/src/main.rs index 24d8344a..3b427fbb 100644 --- a/rust-exercise/src/main.rs +++ b/rust-exercise/src/main.rs @@ -31,24 +31,24 @@ use struct_data_type::*; use thread_syntax::*; use variables_function::*; -pub mod panic_function; -pub mod thread_syntax; +pub mod closures_syntax; +pub mod collection_function; +pub mod control_function; +pub mod enum_data_type; +pub mod example_guessing_game; pub mod generic_traits_lifetimes; pub mod iterator_demonstration; -pub mod struct_data_type; -pub mod simple_array_data_type; +pub mod macro_syntax; pub mod match_syntax; -pub mod example_guessing_game; -pub mod variables_function; -pub mod enum_data_type; pub mod method_syntax; -pub mod collection_function; -pub mod point_function; -pub mod control_function; pub mod other_function; -pub mod closures_syntax; +pub mod panic_function; +pub mod point_function; +pub mod simple_array_data_type; pub mod smart_point; -pub mod macro_syntax; +pub mod struct_data_type; +pub mod thread_syntax; +pub mod variables_function; /// 引用和借用:https://dreamylost.cn/rust/Rust-Rust%E5%AD%A6%E4%B9%A0%E4%B9%8B%E5%BC%95%E7%94%A8%E4%B8%8E%E5%80%9F%E7%94%A8.html /// 所有权:https://dreamylost.cn/rust/Rust-%E6%89%80%E6%9C%89%E6%9D%83.html @@ -64,7 +64,7 @@ fn main() { println!("===================="); expr_function(); println!("===================="); - println!("{}", five());//打印字符串,不能直接println!(five()) + println!("{}", five()); //打印字符串,不能直接println!(five()) println!("===================="); control_function(); println!("===================="); diff --git a/rust-exercise/src/match_syntax.rs b/rust-exercise/src/match_syntax.rs index c8943887..ad691967 100644 --- a/rust-exercise/src/match_syntax.rs +++ b/rust-exercise/src/match_syntax.rs @@ -3,7 +3,7 @@ pub fn match_syntax2() { let some_u8_value = Some(0u8); match some_u8_value { Some(3) => println!("three"), - _ => () //这行是多余的样板代码 + _ => (), //这行是多余的样板代码 } //使用if let 省略上面的样板代码 @@ -65,7 +65,6 @@ pub fn match_syntax() { } } - ///绑定到值的匹配 #[derive(Debug)] enum UsState { @@ -112,6 +111,6 @@ pub fn match_syntax() { 3 => println!("three"), 5 => println!("five"), 7 => println!("seven"), - _ => () + _ => (), } } diff --git a/rust-exercise/src/method_syntax.rs b/rust-exercise/src/method_syntax.rs index b5ea5b71..09152039 100644 --- a/rust-exercise/src/method_syntax.rs +++ b/rust-exercise/src/method_syntax.rs @@ -21,11 +21,17 @@ pub fn method_syntax() { //关联函数,没有self,类似其他语言的静态方法,但不是rust方法 fn square(size: u32) -> Rectangle { - Rectangle { width: size, height: size } + Rectangle { + width: size, + height: size, + } } } - let rect1 = Rectangle { width: 30, height: 50 }; + let rect1 = Rectangle { + width: 30, + height: 50, + }; ///c/c++中如果object是一个指针, object->something() 与 (*object).something()等价 ///Rust没有等效于->运算符;相反,Rust具有称为自动引用和取消引用的功能。调用方法是Rust少数具有这种行为的地方之一。 @@ -38,9 +44,18 @@ pub fn method_syntax() { ); ///方法参数 - let rect1 = Rectangle { width: 30, height: 50 }; - let rect2 = Rectangle { width: 10, height: 40 }; - let rect3 = Rectangle { width: 60, height: 45 }; + let rect1 = Rectangle { + width: 30, + height: 50, + }; + let rect2 = Rectangle { + width: 10, + height: 40, + }; + let rect3 = Rectangle { + width: 60, + height: 45, + }; println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); @@ -48,7 +63,7 @@ pub fn method_syntax() { ///impl块的另一个有用功能是允许我们在不以self为参数的impl块中定义函数。这些之所以称为关联函数,是因为它们与struct相关联。 ///它们仍然是函数,而不是方法,因为它们没有可使用的结构实例 ///关联函数通常用于将返回该结构的新实例的构造函数。例如,我们可以提供一个关联的函数,该函数将具有一个维度参数并将其用作宽度和高度,从而使创建矩形矩形变得更加容易,而不必两次指定相同的值: - let sq = Rectangle::square(3);//类似调用静态方法 + let sq = Rectangle::square(3); //类似调用静态方法 println!("sq is {:#?}", sq); ///关联函数与结构体相关,但是没有self实例,他们仍是函数!!! @@ -61,4 +76,4 @@ pub fn method_syntax() { let test = Test::test(); println!("test is {:#?}", test); -} \ No newline at end of file +} diff --git a/rust-exercise/src/other_function.rs b/rust-exercise/src/other_function.rs index 7d0cc495..f1015c45 100644 --- a/rust-exercise/src/other_function.rs +++ b/rust-exercise/src/other_function.rs @@ -12,23 +12,24 @@ pub fn crate_function() { // lib::eat_at_restaurant2(); //} - pub fn return_function() { - let s1 = gives_ownership(); // lets_ownership移动其返回值到s1中 + let s1 = gives_ownership(); // lets_ownership移动其返回值到s1中 - let s2 = String::from("hello"); // s2进入范围 + let s2 = String::from("hello"); // s2进入范围 - let s3 = takes_and_gives_back(s2); // s2被移入takes_and_gives_back, takes_and_gives_back的返回值被移动到s3 + let s3 = takes_and_gives_back(s2); // s2被移入takes_and_gives_back, takes_and_gives_back的返回值被移动到s3 println!("{},{}", s1, s3); - fn gives_ownership() -> String { // gives_ownership会其返回值移动到调用它的函数中 + fn gives_ownership() -> String { + // gives_ownership会其返回值移动到调用它的函数中 let some_string = String::from("hello"); // some_string进入范围 - some_string // 返回some_string字符串并移到调用函数 + some_string // 返回some_string字符串并移到调用函数 } // take_and_gives_back将获取一个String并返回一个 - fn takes_and_gives_back(a_string: String) -> String { // a_string进入范围 - a_string // 返回a_string并移至调用函数 + fn takes_and_gives_back(a_string: String) -> String { + // a_string进入范围 + a_string // 返回a_string并移至调用函数 } } @@ -67,4 +68,4 @@ pub fn five() -> i32 { pub fn another_function(x: i32) { //传参数的rust函数,与Scala一样,名称: 类型 println!("The value of x is: {}", x); -} \ No newline at end of file +} diff --git a/rust-exercise/src/panic_function.rs b/rust-exercise/src/panic_function.rs index 76457236..85210cab 100644 --- a/rust-exercise/src/panic_function.rs +++ b/rust-exercise/src/panic_function.rs @@ -1,7 +1,7 @@ -use std::{fs, io}; use std::error::Error; use std::fs::File; use std::io::{ErrorKind, Read}; +use std::{fs, io}; ///恐慌使用(error) pub fn panic_function() { @@ -11,7 +11,7 @@ pub fn panic_function() { Err(error) => match error.kind() { ErrorKind::NotFound => match File::create("hello.txt") { Ok(fc) => fc, - Err(e) => panic!("Problem creating the file: {:?}", e),//panic!打印错误信息,panic是不可恢复的错误 + Err(e) => panic!("Problem creating the file: {:?}", e), //panic!打印错误信息,panic是不可恢复的错误 }, other_error => panic!("Problem opening the file: {:?}", other_error), }, @@ -50,7 +50,7 @@ pub fn panic_function() { ///传播错误的捷径:?运算符 fn read_username_from_file2() -> Result { - let mut f = File::open("hello.txt")?;//使用?运算符将错误返回到调用代码的函数,将错误自身转换为返回的错误类型。(From特质 from函数) + let mut f = File::open("hello.txt")?; //使用?运算符将错误返回到调用代码的函数,将错误自身转换为返回的错误类型。(From特质 from函数) let mut s = String::new(); f.read_to_string(&mut s)?; Ok(s) @@ -83,12 +83,10 @@ pub fn panic_function() { if value < 1 || value > 100 { panic!("Guess value must be between 1 and 100, got {}.", value); } - Guess { - value - } + Guess { value } } pub fn value(&self) -> i32 { self.value } } -} \ No newline at end of file +} diff --git a/rust-exercise/src/point_function.rs b/rust-exercise/src/point_function.rs index f56d78d8..079211b7 100644 --- a/rust-exercise/src/point_function.rs +++ b/rust-exercise/src/point_function.rs @@ -2,11 +2,10 @@ ///Rust中最常见的一种指针是引用,还有其他指针 ///在使用所有权和借用概念的Rust中,引用和智能指针之间的另一个区别是,引用是仅借用数据的指针。相反,在许多情况下,智能指针拥有它们指向的数据。 pub fn empty_point_function() { - //let reference_to_nothing = dangle(); let reference_to_nothing = no_dangle(); fn no_dangle() -> String { - String::from("hello")// 直接反回函数的值,不能加分号 + String::from("hello") // 直接反回函数的值,不能加分号 } //编译报错,因为s是在dangle内部创建的,所以当dangle的代码完成时,将释放s。但是我们试图返回对它的引用。这意味着该引用将指向无效的String。Rust不允许我们这样做。 // fn dangle() -> &String { diff --git a/rust-exercise/src/simple_array_data_type.rs b/rust-exercise/src/simple_array_data_type.rs index aaf1065d..d0c374d1 100644 --- a/rust-exercise/src/simple_array_data_type.rs +++ b/rust-exercise/src/simple_array_data_type.rs @@ -3,7 +3,6 @@ pub fn simple_array_data_type() { ///--release模式下,整数溢出将会变为最小值 ///在u8(0-255)类型下,256变为0,257变为1,依此类推 - ///默认浮点类型是f64,相当于Java double,IEEE754标准 let x = 2.0; // f64 @@ -60,7 +59,7 @@ pub fn simple_array_data_type() { let second = a[1]; ///Rust通过立即退出而不是允许内存访问并继续操作来保护您免受此类错误的侵害 - let element = a[0];//若下标大于数组索引则运行时检查并报错退出"error: index out of bounds: the len is 5 but the index is 10" + let element = a[0]; //若下标大于数组索引则运行时检查并报错退出"error: index out of bounds: the len is 5 but the index is 10" } ///rust String比较复杂 @@ -70,16 +69,15 @@ pub fn string_function() { println!("{}", s); //打印 hello, world! + let s = String::from("hello"); // s进入范围 - let s = String::from("hello"); // s进入范围 - - takes_ownership(s); // s的值移动到函数,所以在这里不再有效 - //println!("{}", s);//编译错误:value borrowed here after move。出借后的s被移动,后续不可用 + takes_ownership(s); // s的值移动到函数,所以在这里不再有效 + //println!("{}", s);//编译错误:value borrowed here after move。出借后的s被移动,后续不可用 - let x = 5; // x进入范围 - makes_copy(x); // x将移动到函数 - //但是i32是Copy,所以之后还可以使用 - println!("{}", x);//正常打印 + let x = 5; // x进入范围 + makes_copy(x); // x将移动到函数 + //但是i32是Copy,所以之后还可以使用 + println!("{}", x); //正常打印 fn takes_ownership(some_string: String) { println!("{}", some_string); @@ -88,4 +86,4 @@ pub fn string_function() { fn makes_copy(some_integer: i32) { println!("{}", some_integer); } -} \ No newline at end of file +} diff --git a/rust-exercise/src/smart_point.rs b/rust-exercise/src/smart_point.rs index 1caa4aec..2fa1d1b5 100644 --- a/rust-exercise/src/smart_point.rs +++ b/rust-exercise/src/smart_point.rs @@ -43,7 +43,7 @@ pub fn box_function() { &self.0 } } - assert_eq!(5, *y);//*(y.deref()),如果该deref方法直接返回该值而不是对该值的引用,则该值将移出self。因为我们*操作时一般不需要拥有这个所有权 + assert_eq!(5, *y); //*(y.deref()),如果该deref方法直接返回该值而不是对该值的引用,则该值将移出self。因为我们*操作时一般不需要拥有这个所有权 ///隐式的强制实现deref特质 fn hello(name: &str) { @@ -52,7 +52,7 @@ pub fn box_function() { let m = MyBox::new(String::from("Rust")); hello(&m); let m = MyBox::new(String::from("Rust")); - hello(&(*m)[..]);//如果Rust没有实现deref,代码应该写成这样(虽然两者都可用,但是这个更麻烦) + hello(&(*m)[..]); //如果Rust没有实现deref,代码应该写成这样(虽然两者都可用,但是这个更麻烦) //由于有借用规则,如果您有可变引用,则该可变引用必须是对该数据的唯一引用(否则,程序将无法编译)。 //将一个可变引用转换为一个不可变引用将永远不会违反借用规则。 @@ -62,7 +62,6 @@ pub fn box_function() { //当T: DerefMut 从 &mut T 到 &mut U //当T: Deref 从 &mut T 到 &U - ///在实例超出范围时将打印该结构 struct CustomSmartPointer { data: String, @@ -74,13 +73,19 @@ pub fn box_function() { println!("Dropping CustomSmartPointer with data `{}`!", self.data); } } - let c = CustomSmartPointer { data: String::from("my stuff") }; - let d = CustomSmartPointer { data: String::from("other stuff") }; + let c = CustomSmartPointer { + data: String::from("my stuff"), + }; + let d = CustomSmartPointer { + data: String::from("other stuff"), + }; println!("CustomSmartPointers created."); - let c = CustomSmartPointer { data: String::from("some data") }; + let c = CustomSmartPointer { + data: String::from("some data"), + }; println!("CustomSmartPointer created."); - drop(c);//希望早点被删除,调用std::mem::drop在值超出范围之前显式删除它。与c++析构函数相同,drop只被调用一次 + drop(c); //希望早点被删除,调用std::mem::drop在值超出范围之前显式删除它。与c++析构函数相同,drop只被调用一次 println!("CustomSmartPointer dropped before the end of main."); ///使用Rc(引用计数)智能指针共享数据 @@ -90,14 +95,14 @@ pub fn box_function() { } use ListRc::*; let a = Rc::new(ConsRc(5, Rc::new(ConsRc(10, Rc::new(NilRc))))); - println!("count after creating a = {}", Rc::strong_count(&a));//引用计数=1 - let b = ConsRc(3, Rc::clone(&a));//clone无额外性能开销,实际仅增加了引用计数而不是真的深拷贝数据 - println!("count after creating b = {}", Rc::strong_count(&a));//引用计数=2 + println!("count after creating a = {}", Rc::strong_count(&a)); //引用计数=1 + let b = ConsRc(3, Rc::clone(&a)); //clone无额外性能开销,实际仅增加了引用计数而不是真的深拷贝数据 + println!("count after creating b = {}", Rc::strong_count(&a)); //引用计数=2 { let c = ConsRc(4, Rc::clone(&a)); - println!("count after creating c = {}", Rc::strong_count(&a));//引用计数=3 - }//超出范围了,引用计数变为2 - println!("count after c goes out of scope = {}", Rc::strong_count(&a));//Weak 弱引用计数 + println!("count after creating c = {}", Rc::strong_count(&a)); //引用计数=3 + } //超出范围了,引用计数变为2 + println!("count after c goes out of scope = {}", Rc::strong_count(&a)); //Weak 弱引用计数 //运行时执行检查不可变或可变的借用,RefCell,因为RefCell允许在运行时检查可变借位,所以即使RefCell不可变,您也可以更改RefCell内部的值。 //Box允许在编译时检查不可变或可变的借用 @@ -116,7 +121,10 @@ pub struct LimitTracker<'a, T: Messenger> { max: usize, } -impl<'a, T> LimitTracker<'a, T> where T: Messenger { +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ pub fn new(messenger: &T, max: usize) -> LimitTracker { LimitTracker { messenger, @@ -125,16 +133,17 @@ impl<'a, T> LimitTracker<'a, T> where T: Messenger { } } - pub fn set_value(&mut self, value: usize) { self.value = value; let percentage_of_max = self.value as f64 / self.max as f64; if percentage_of_max >= 1.0 { self.messenger.send("Error: You are over your quota!"); } else if percentage_of_max >= 0.9 { - self.messenger.send("Urgent warning: You've used up over 90% of your quota!"); + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); } else if percentage_of_max >= 0.75 { - self.messenger.send("Warning: You've used up over 75% of your quota!"); + self.messenger + .send("Warning: You've used up over 75% of your quota!"); } } } @@ -149,20 +158,21 @@ mod tests { struct MockMessenger { //sent_messages: Vec, sent_messages: RefCell>, - } impl MockMessenger { fn new() -> MockMessenger { //MockMessenger { sent_messages: vec![] } - MockMessenger { sent_messages: RefCell::new(vec![]) } + MockMessenger { + sent_messages: RefCell::new(vec![]), + } } } impl Messenger for MockMessenger { fn send(&self, message: &str) { //self.sent_messages.push(String::from(message));//编译报错 - self.sent_messages.borrow_mut().push(String::from(message));//可变借用 + self.sent_messages.borrow_mut().push(String::from(message)); //可变借用 } } diff --git a/rust-exercise/src/struct_data_type.rs b/rust-exercise/src/struct_data_type.rs index cbbac192..2f29da78 100644 --- a/rust-exercise/src/struct_data_type.rs +++ b/rust-exercise/src/struct_data_type.rs @@ -7,7 +7,8 @@ pub fn struct_data_type() { active: bool, } - let mut user1 = User { //必须定义为可变的才能修改结构体的内容 + let mut user1 = User { + //必须定义为可变的才能修改结构体的内容 email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, @@ -73,7 +74,10 @@ pub fn struct_data_type() { width * height } - println!("The area of the rectangle is {} square pixels.", area(width1, height1)); + println!( + "The area of the rectangle is {} square pixels.", + area(width1, height1) + ); //使用元祖 fn area_tuple(dimensions: (u32, u32)) -> u32 { @@ -98,12 +102,15 @@ pub fn struct_data_type() { rectangle.width * rectangle.height } - let rect1 = Rectangle { width: 30, height: 50 }; + let rect1 = Rectangle { + width: 30, + height: 50, + }; println!( "The area of the rectangle is {} square pixels.", area_struct(&rect1) ); //这将会报错,因为该结构体不支持显示:`Rectangle` doesn't implement `std::fmt::Display` - println!("rect1 is {:#?}", rect1);//{:?}使用调试模式打印也会报错:`Rectangle` doesn't implement `std::fmt::Debug`,{:#?} 格式化打印 -} \ No newline at end of file + println!("rect1 is {:#?}", rect1); //{:?}使用调试模式打印也会报错:`Rectangle` doesn't implement `std::fmt::Debug`,{:#?} 格式化打印 +} diff --git a/rust-exercise/src/thread_syntax.rs b/rust-exercise/src/thread_syntax.rs index a09c6807..2e50b196 100644 --- a/rust-exercise/src/thread_syntax.rs +++ b/rust-exercise/src/thread_syntax.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, mpsc, Mutex}; +use std::sync::{mpsc, Arc, Mutex}; use std::thread; use std::time::Duration; @@ -13,7 +13,7 @@ pub fn create_thread() { for i in 1..5 { println!("hi number {} from the main thread!", i); - thread::sleep(Duration::from_millis(1));//短暂停止,最终仍取决于操作系统如何调度线程。 + thread::sleep(Duration::from_millis(1)); //短暂停止,最终仍取决于操作系统如何调度线程。 } } @@ -32,13 +32,14 @@ pub fn join_thread() { thread::sleep(Duration::from_millis(1)); } ///阻塞当前正在运行的线程,直到由该句柄表示的线程终止 - handle.join().unwrap();//即thread::spawn先执行,main后执行 + handle.join().unwrap(); //即thread::spawn先执行,main后执行 } pub fn use_var_thread() { ///尝试在另一个线程中使用由主线程创建的向量 let v = vec![1, 2, 3]; - let handle = thread::spawn(move || {//必须在闭包前加move,强制获取v变量的所有权而不是借用这个值 + let handle = thread::spawn(move || { + //必须在闭包前加move,强制获取v变量的所有权而不是借用这个值 println!("Here's a vector: {:?}", v); }); //v不能再被主线程使用,所有权已经转移 @@ -56,7 +57,7 @@ pub fn channel_thread() { tx.send(val).unwrap(); }); //使用rx接收器接收消息 - let received = rx.recv().unwrap();//try_recv方法不会阻塞 + let received = rx.recv().unwrap(); //try_recv方法不会阻塞 println!("Got: {}", received); } @@ -150,4 +151,3 @@ pub fn mutex_multi_thread() { } println!("Result: {}", *counter.lock().unwrap()); } - diff --git a/rust-exercise/src/variables_function.rs b/rust-exercise/src/variables_function.rs index 16cd0594..f66cfcc1 100644 --- a/rust-exercise/src/variables_function.rs +++ b/rust-exercise/src/variables_function.rs @@ -8,7 +8,7 @@ pub fn variables_function() { let mut y = 6; println!("The value of y is: {}", y); - y = 7;//可变的变量 + y = 7; //可变的变量 println!("The value of y is: {}", y); //常量,必须指定类型,不可省略 const MAX_POINTS: u32 = 100_000; @@ -36,26 +36,22 @@ pub fn try_change_function() { let mut s = String::from("hello"); change(&mut s); - let mut s = String::from("hello"); let r1 = &mut s; //let r2 = &mut s;//可变引用只能被出借一次,这里将会编译报错 //println!("{}, {}", r1, r2); - let mut s = String::from("hello"); { let r1 = &mut s; } // r1在这里超出范围,因此我们可以毫无问题地进行新引用。 - let r2 = &mut s;//正常使用,虽然上面已经用过s - + let r2 = &mut s; //正常使用,虽然上面已经用过s let mut s = String::from("hello"); - let r1 = &s; // 没问题,与上面两次mut出借不一样,这里是没有mut,所以对于不可变引用,可以使用多次次,且不可在拥有不可变引用时同时拥有可变引用 - let r2 = &s; // 没问题 - //let r3 = &mut s; // 有问题,不可变在后面却是可变,不允许,编译报错 - //println!("{}, {}, and {}", r1, r2, r3); - + let r1 = &s; // 没问题,与上面两次mut出借不一样,这里是没有mut,所以对于不可变引用,可以使用多次次,且不可在拥有不可变引用时同时拥有可变引用 + let r2 = &s; // 没问题 + //let r3 = &mut s; // 有问题,不可变在后面却是可变,不允许,编译报错 + //println!("{}, {}, and {}", r1, r2, r3); let mut s = String::from("hello"); @@ -69,7 +65,6 @@ pub fn try_change_function() { } pub fn expr_function() { - //赋值需要返回值,rust语句没有返回值,不同于其他语言赋值可以连用 // let x = (let y = 6); @@ -82,10 +77,10 @@ pub fn expr_function() { println!("The value of y is: {}", y); -// String转&str的几种办法: -// 1. s.deref() 手动解引用 -// 2. &*s 同上 -// 3. s.as_ref() -// 4. &s[..] -// 5. s.borrow() 需要use std::borrow::Borrow -} \ No newline at end of file + // String转&str的几种办法: + // 1. s.deref() 手动解引用 + // 2. &*s 同上 + // 3. s.as_ref() + // 4. &s[..] + // 5. s.borrow() 需要use std::borrow::Borrow +} diff --git a/rust-http/src/lib.rs b/rust-http/src/lib.rs index f9cbfbdd..b4331378 100644 --- a/rust-http/src/lib.rs +++ b/rust-http/src/lib.rs @@ -1,7 +1,7 @@ use core::result; -use std::{fmt, thread}; use std::process::id; -use std::sync::{Arc, mpsc, Mutex}; +use std::sync::{mpsc, Arc, Mutex}; +use std::{fmt, thread}; ///定义线程交互消息 enum Message { @@ -39,18 +39,21 @@ impl ThreadPool { pub fn new(size: usize) -> ThreadPool { assert!(size > 0, "ThreadPool size cannot less than 0"); let (sender, receiver) = mpsc::channel(); - let receiver = Arc::new(Mutex::new(receiver));//Arc共享接收器 Mutex任务互斥 - //初始化大小 + let receiver = Arc::new(Mutex::new(receiver)); //Arc共享接收器 Mutex任务互斥 + //初始化大小 let mut workers = Vec::with_capacity(size); for id in 0..size { //创建一些线程并将其存储在向量中 - workers.push(Worker::new(id, Arc::clone(&receiver)));//共享receiver + workers.push(Worker::new(id, Arc::clone(&receiver))); //共享receiver } ThreadPool { workers, sender } } //参考thread::spawn对其参数的限制 - pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static { + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { self.sender.send(Message::NewJob(Box::new(f))).unwrap(); } } @@ -66,8 +69,9 @@ impl Drop for ThreadPool { println!("Shutting down all workers."); for worker in &mut self.workers { println!("Shutting down worker {}", worker.id); - if let Some(thread) = worker.thread.take() {//take出工作线程并置为None - thread.join().unwrap();//等待主线程的 + if let Some(thread) = worker.thread.take() { + //take出工作线程并置为None + thread.join().unwrap(); //等待主线程的 } } } @@ -98,6 +102,9 @@ impl Worker { } } }); - Worker { id, thread: Some(thread) } + Worker { + id, + thread: Some(thread), + } } } diff --git a/rust-http/src/main.rs b/rust-http/src/main.rs index 7fe14aca..e4015ea1 100644 --- a/rust-http/src/main.rs +++ b/rust-http/src/main.rs @@ -1,7 +1,7 @@ -use std::{fs, thread}; use std::io::{Read, Write}; use std::net::{TcpListener, TcpStream}; use std::time::Duration; +use std::{fs, thread}; use lib::ThreadPool; @@ -37,4 +37,4 @@ fn handle_connection(mut stream: TcpStream) { let response = format!("{}{}", status_line, contents); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap(); -} \ No newline at end of file +} diff --git a/rust-leetcode/README.md b/rust-leetcode/README.md index 7c0b8dc0..a9bfabf2 100644 --- a/rust-leetcode/README.md +++ b/rust-leetcode/README.md @@ -7,124 +7,122 @@ Leetcode Rust 实现 无注明,默认是LeetCode系列 -以下按照Solution.rs源码中的行号往下递增 +* [面试题 22 链表中倒数第k个节点](src/interview_22.rs) -* [面试题 22 链表中倒数第k个节点](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L153) +* [1351 统计有序矩阵中的负数](src/leetcode_1351.rs) -* [1351 统计有序矩阵中的负数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L189) +* [面试题 02.02 返回倒数第 k 个节点值](src/interview_02_02.rs) -* [面试题 02.02 返回倒数第 k 个节点值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L95) +* [面试题 55 - I 二叉树的深度](src/interview_55_1.rs) -* [面试题 55 - I 二叉树的深度](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L207) +* [面试题 04.02 最小高度树](src/interview_04_02.rs) -* [面试题 04.02 最小高度树](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L229) +* [1281 整数的各位积和之差](src/leetcode_1281.rs) -* [1281 整数的各位积和之差](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L255) +* [面试题 58 - II 左旋转字符串](src/interview_58_2.rs) -* [面试题 58 - II 左旋转字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L276) +* [1365 有多少小于当前数字的数字](src/leetcode_1365.rs) -* [1365 有多少小于当前数字的数字](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L292) +* [1342 将数字变成 0 的操作次数](src/leetcode_1342.rs) -* [1342 将数字变成 0 的操作次数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L316) +* [1313 解压缩编码列表](src/leetcode_1313.rs) -* [1313 解压缩编码列表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L338) +* [面试题 17 打印从1到最大的n位数](src/interview_17.rs) -* [面试题 17 打印从1到最大的n位数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L364) +* [面试题 05 替换空格](src/interview_05.rs) -* [面试题 05 替换空格](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L429) +* [1221 分割平衡字符串](src/leetcode_1221.rs) -* [1221 分割平衡字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L443) +* [面试题 06 从尾到头打印链表](src/interview_06.rs) -* [面试题 06 从尾到头打印链表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L481) +* [938 二叉搜索树的范围和](src/leetcode_938.rs) -* [938 二叉搜索树的范围和](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L505) +* [1021 删除最外层的括号](src/leetcode_1021.rs) -* [1021 删除最外层的括号](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L557) +* [面试题 24 反转链表](src/interview_24.rs) -* [面试题 24 反转链表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L605) +* [1252 奇数值单元格的数目](src/leetcode_1252.rs) -* [1252 奇数值单元格的数目](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L634) +* [1323 6 和 9 组成的最大数字](src/leetcode_1323.rs) -* [1323 6 和 9 组成的最大数字](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L664) +* [617 合并二叉树](src/leetcode_617.rs) -* [617 合并二叉树](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L677) +* [461 汉明距离](src/leetcode_461.rs) -* [461 汉明距离](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L729) +* [709 转换成小写字母](src/leetcode_709.rs) -* [709 转换成小写字母](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L338) +* [1304 和为零的N个唯一整数](src/leetcode_1304.rs) -* [1304 和为零的N个唯一整数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L751) +* [804 唯一摩尔斯密码词](src/leetcode_804.rs) -* [804 唯一摩尔斯密码词](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L810) +* [832 翻转图像](src/leetcode_832.rs) -* [832 翻转图像](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L835) +* [面试题 25 合并两个排序的链表](src/interview_25.rs) -* [面试题 25 合并两个排序的链表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L864) +* [1370 上升下降字符串](src/leetcode_1370.rs) -* [1370 上升下降字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L931) +* [面试题 03.04 化栈为队](src/interview_03_04.rs) -* [面试题 03.04 化栈为队](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L962) +* [1051 高度检查器](src/leetcode_1051.rs) -* [1051 高度检查器](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1023) +* [728 自除数](src/leetcode_728.rs) -* [728 自除数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L045) +* [面试题 01.01 判定字符是否唯一](src/interview_01_01.rs) -* [面试题 01.01 判定字符是否唯一](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1074) +* [1385 两个数组间的距离值](src/leetcode_1385.rs) -* [1385 两个数组间的距离值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1115) +* [面试题 54 二叉搜索树的第k大节点](src/interview_54.rs) -* [面试题 54 二叉搜索树的第k大节点](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1141) +* [面试题 09 用两个栈实现队列](src/interview_09.rs) -* [面试题 09 用两个栈实现队列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1174) +* [面试题 16.07 最大数值](src/interview_16_07.rs) -* [面试题 16.07 最大数值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1218) +* [977 有序数组的平方](src/leetcode_977.rs) -* [977 有序数组的平方](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1265) +* [1380 矩阵中的幸运数](src/leetcode_1380.rs) -* [1380 矩阵中的幸运数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1301) +* [933 最近的请求次数](src/leetcode_933.rs) -* [933 最近的请求次数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1336) +* [561 数组拆分 I](src/leetcode_561.rs) -* [561 数组拆分 I](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1374) +* [1374 生成每种字符都是奇数个的字符串](src/leetcode_1374.rs) -* [1374 生成每种字符都是奇数个的字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1422) +* [1403 非递增顺序的最小子序列](src/leetcode_1403.rs) -* [1403 非递增顺序的最小子序列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1445) +* [557 反转字符串中的单词 III](src/leetcode_557.rs) -* [557 反转字符串中的单词 III](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1469) +* [999 可以被一步捕获的棋子数](src/leetcode_999.rs) -* [999 可以被一步捕获的棋子数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1487) +* [292 Nim 游戏](src/leetcode_292.rs) -* [292 Nim 游戏](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1537) +* [1160 拼写单词](src/leetcode_1160.rs) -* [1160 拼写单词](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1547) +* [1413 逐步求和得到正数的最小值](src/leetcode_1413.rs) -* [1413 逐步求和得到正数的最小值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1582) +* [面试题 32 - II. 从上到下打印二叉树 II](src/interview_32_2.rs) -* [面试题 32 - II. 从上到下打印二叉树 II](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1604) +* [944 删列造序](src/leetcode_944.rs) -* [944 删列造序](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1663) +* [9 回文数](src/leetcode_9.rs) -* [9 回文数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1689) +* [13 罗马数字转整数](src/leetcode_13.rs) -* [13 罗马数字转整数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1730) +* [876 链表的中间结点](src/leetcode_876.rs) -* [876 链表的中间结点](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1811) +* [500 键盘行](src/leetcode_500.rs) -* [500 键盘行](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1836) +* [14 长公共前缀](src/leetcode_14.rs) -* [14 长公共前缀](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1856) +* [20 有效的括号](src/leetcode_20.rs) -* [20 有效的括号](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1952) +* [35 搜索插入位置](src/leetcode_35.rs) -* [35 搜索插入位置](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1982) +* [905 按奇偶排序数组](src/leetcode_905.rs) -* [905 按奇偶排序数组](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2000) +* [1207 独一无二的出现次数](src/leetcode_1207.rs) -* [1207 独一无二的出现次数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2014) +* [38 外观数列](src/leetcode_38.rs) -* [38 外观数列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2036) +* [58 最后一个单词的长度](src/leetcode_58.rs) -* [58 最后一个单词的长度](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2080) - -* [665 非递减数列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2093) \ No newline at end of file +* [665 非递减数列](src/leetcode_665.rs) \ No newline at end of file diff --git a/rust-leetcode/src/interview_01_01.rs b/rust-leetcode/src/interview_01_01.rs new file mode 100644 index 00000000..33fcc52d --- /dev/null +++ b/rust-leetcode/src/interview_01_01.rs @@ -0,0 +1,34 @@ +use crate::pre_structs::Solution; + +///判定字符是否唯一 +impl Solution { + pub fn is_unique(astr: String) -> bool { + let cs = astr.chars(); + //题目没有说明,但这样AC了,假定只有大小写字母 + let mut count = vec![0; ('z' as i32 as usize) + 1]; //123 + for c in cs { + count[(c as i32) as usize] += 1; + } + for &c in count.iter() { + if c > 1 { + return false; + } + } + true + } + //位运算 + pub fn is_unique2(astr: String) -> bool { + let cs = astr.chars(); + let mut mark = 0; + let mut mark_bit = 0; + for c in cs { + mark_bit = c as i32 - ('a' as i32); + if (mark & (1 << mark_bit)) != 0 { + return false; + } else { + mark |= 1 << mark_bit + } + } + true + } +} diff --git a/rust-leetcode/src/interview_02_02.rs b/rust-leetcode/src/interview_02_02.rs new file mode 100644 index 00000000..8e01fded --- /dev/null +++ b/rust-leetcode/src/interview_02_02.rs @@ -0,0 +1,49 @@ +use std::borrow::Borrow; +use std::collections::VecDeque; + +use crate::pre_structs::{ListNode, Solution}; + +///返回倒数第 k 个节点 +impl Solution { + pub fn kth_to_last(head: Option>, k: i32) -> i32 { + let mut nodes = head; + let mut qs = VecDeque::new(); + loop { + if let Some(node) = nodes.borrow() { + qs.push_back(node.val); + nodes = node.next.clone(); + } else { + break; + } + } + + let i = qs.len() - k as usize; + let ret = qs.get(i); + *ret.unwrap() + } + + //倒数第k个,位置就是len-k。即快指针先走k步,然后2个指针同时走,快指针到达尾时,慢指针的位置就是第len-k个元素。此时快指针刚好走完一圈 + pub fn kth_to_last2(head: Option>, k: i32) -> i32 { + let mut i = k; + let mut fast = head.as_ref(); //clone也可以,但没有必要,不能copy,没有实现Copy + let mut slow = head.as_ref(); + while i > 0 { + if let Some(node) = fast.borrow() { + fast = node.next.as_ref(); + i -= 1; + } else { + break; + } + } + + while fast != None { + if let Some(node) = fast.borrow() { + fast = node.next.as_ref(); + if let Some(node) = slow.borrow() { + slow = node.next.as_ref(); + } + } + } + slow.unwrap().val + } +} diff --git a/rust-leetcode/src/interview_03_04.rs b/rust-leetcode/src/interview_03_04.rs new file mode 100644 index 00000000..ba36b6b4 --- /dev/null +++ b/rust-leetcode/src/interview_03_04.rs @@ -0,0 +1,51 @@ +use std::collections::VecDeque; + +///化栈为队 +struct MyQueue { + stack1: VecDeque>, + stack2: VecDeque>, +} + +impl MyQueue { + /** Initialize your data structure here. */ + fn new() -> Self { + MyQueue { + stack1: VecDeque::new(), + stack2: VecDeque::new(), + } + } + + /** Push element x to the back of queue. */ + fn push(&mut self, x: i32) { + self.stack1.push_back(Some(x)) + } + + /** Removes the element from in front of queue and returns that element. */ + fn pop(&mut self) -> i32 { + return MyQueue::peek_pop(self, true); + } + + fn peek_pop(queue: &mut MyQueue, flag: bool) -> i32 { + if queue.stack2.is_empty() { + while !queue.stack1.is_empty() { + queue.stack2.push_back(queue.stack1.pop_back().unwrap()); + } + } + let ret = if flag { + queue.stack2.pop_back().unwrap() + } else { + queue.stack2.back().unwrap().clone() + }; + ret.unwrap() + } + + /** Get the front element. */ + fn peek(&mut self) -> i32 { + return MyQueue::peek_pop(self, false); + } + + /** Returns whether the queue is empty. */ + fn empty(&mut self) -> bool { + self.stack1.is_empty() && self.stack2.is_empty() + } +} diff --git a/rust-leetcode/src/interview_04_02.rs b/rust-leetcode/src/interview_04_02.rs new file mode 100644 index 00000000..f3c8d2b6 --- /dev/null +++ b/rust-leetcode/src/interview_04_02.rs @@ -0,0 +1,25 @@ +use std::cell::RefCell; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///最小高度树 +impl Solution { + pub fn sorted_array_to_bst(nums: Vec) -> Option>> { + fn buildTree(nums: &Vec, l: i32, r: i32) -> Option>> { + if l > r { + return None; + } + if l == r { + return Some(Rc::new(RefCell::new(TreeNode::new(nums[l as usize])))); + } + let mid = l + (r - l) / 2; + let mut root = TreeNode::new(nums[mid as usize]); + root.left = buildTree(nums, l, mid - 1); + root.right = buildTree(nums, mid + 1, r); + return Some(Rc::new(RefCell::new(root))); + } + + return buildTree(&nums, 0, (nums.len() - 1) as i32); + } +} diff --git a/rust-leetcode/src/interview_05.rs b/rust-leetcode/src/interview_05.rs new file mode 100644 index 00000000..98755b15 --- /dev/null +++ b/rust-leetcode/src/interview_05.rs @@ -0,0 +1,9 @@ +use crate::pre_structs::Solution; + +///替换空格 +impl Solution { + pub fn replace_space(s: String) -> String { + let mut str = s; + str.replace(" ", "%20") + } +} diff --git a/rust-leetcode/src/interview_06.rs b/rust-leetcode/src/interview_06.rs new file mode 100644 index 00000000..ecbf2f5f --- /dev/null +++ b/rust-leetcode/src/interview_06.rs @@ -0,0 +1,19 @@ +use crate::pre_structs::{ListNode, Solution}; + +///从尾到头打印链表 +impl Solution { + pub fn reverse_print(head: Option>) -> Vec { + let mut ret = Vec::::new(); + let mut node = head.as_ref(); + loop { + if let Some(root) = node { + ret.push(root.val); + node = root.next.as_ref(); + } else { + break; + } + } + ret.reverse(); + ret + } +} diff --git a/rust-leetcode/src/interview_09.rs b/rust-leetcode/src/interview_09.rs new file mode 100644 index 00000000..c74969e2 --- /dev/null +++ b/rust-leetcode/src/interview_09.rs @@ -0,0 +1,38 @@ +use std::collections::VecDeque; + +///用两个栈实现队列 +struct CQueue { + stack1: VecDeque>, + stack2: VecDeque>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl CQueue { + fn new() -> Self { + CQueue { + stack1: VecDeque::new(), + stack2: VecDeque::new(), + } + } + + fn append_tail(&mut self, value: i32) { + self.stack1.push_back(Some(value)) + } + + fn delete_head(&mut self) -> i32 { + if self.stack2.is_empty() { + while !self.stack1.is_empty() { + self.stack2.push_back(self.stack1.pop_back().unwrap()); + } + } + let e = self.stack2.pop_back(); + if e.is_none() { + -1 + } else { + e.unwrap().unwrap() + } + } +} diff --git a/rust-leetcode/src/interview_16_07.rs b/rust-leetcode/src/interview_16_07.rs new file mode 100644 index 00000000..178385af --- /dev/null +++ b/rust-leetcode/src/interview_16_07.rs @@ -0,0 +1,14 @@ +use crate::pre_structs::Solution; + +///最大数值 +impl Solution { + //不能使用if-else 比较运算符 + //max(a, b) = ((a + b) + abs(a - b)) / 2。 + pub fn maximum(a: i32, b: i32) -> i32 { + let mut a = a as i64; + let mut b = b as i64; + b = a - b; + a -= b & (b >> 32); + a as i32 + } +} diff --git a/rust-leetcode/src/interview_17.rs b/rust-leetcode/src/interview_17.rs new file mode 100644 index 00000000..9407f793 --- /dev/null +++ b/rust-leetcode/src/interview_17.rs @@ -0,0 +1,49 @@ +use crate::pre_structs::Solution; + +///打印从1到最大的n位数 +impl Solution { + //8ms + pub fn print_numbers(n: i32) -> Vec { + let mut max_num = String::new(); + for i in 1..=n { + max_num.push('9') + } + let mut ret = Vec::new(); + for i in 1..=max_num.parse::().unwrap() { + ret.push(i); + } + ret + } + + //8ms + pub fn print_numbers2(n: i32) -> Vec { + let mut ret = Vec::new(); + let x: i32 = 10; + for i in 1..x.pow(n as u32) { + ret.push(i); + } + ret + } + + //20ms + pub fn print_numbers3(n: i32) -> Vec { + //快速幂 + fn pow(mut base: i32, mut index: i32) -> i32 { + let mut ret = 1; + while index > 0 { + if index & 1 == 1 { + ret *= base; + } + index /= 2; + base *= base; + } + ret + } + + let mut ret = Vec::new(); + for i in 1..pow(10, n) { + ret.push(i); + } + ret + } +} diff --git a/rust-leetcode/src/interview_22.rs b/rust-leetcode/src/interview_22.rs new file mode 100644 index 00000000..176340d8 --- /dev/null +++ b/rust-leetcode/src/interview_22.rs @@ -0,0 +1,28 @@ +use std::borrow::Borrow; + +use crate::pre_structs::{ListNode, Solution}; + +///链表中倒数第k个节点 +impl Solution { + pub fn get_kth_from_end(head: Option>, k: i32) -> Option> { + let mut i = k; + let mut fast = head.as_ref(); + let mut slow = head.as_ref(); + while i > 0 { + if let Some(node) = fast.borrow() { + fast = node.next.as_ref(); + i -= 1; + } + } + + while fast != None { + if let Some(node) = fast.borrow() { + fast = node.next.as_ref(); + if let Some(node) = slow.borrow() { + slow = node.next.as_ref(); + } + } + } + Some(slow.unwrap().clone()) + } +} diff --git a/rust-leetcode/src/interview_24.rs b/rust-leetcode/src/interview_24.rs new file mode 100644 index 00000000..3e05d3ff --- /dev/null +++ b/rust-leetcode/src/interview_24.rs @@ -0,0 +1,20 @@ +use crate::pre_structs::{ListNode, Solution}; + +///反转链表 leetcode 206 +impl Solution { + pub fn reverse_list(head: Option>) -> Option> { + let mut pre = None; + let mut tmp = head; + loop { + //每次让head指向的节点指向pre指向的节点 + if let Some(mut head) = tmp { + tmp = head.next; + head.next = pre; + pre = Some(head); + } else { + break; + } + } + pre + } +} diff --git a/rust-leetcode/src/interview_25.rs b/rust-leetcode/src/interview_25.rs new file mode 100644 index 00000000..e6e76127 --- /dev/null +++ b/rust-leetcode/src/interview_25.rs @@ -0,0 +1,58 @@ +use crate::pre_structs::{ListNode, Solution}; + +///合并两个排序的链表 +impl Solution { + pub fn merge_two_lists( + l1: Option>, + l2: Option>, + ) -> Option> { + let mut result_head: Option> = Some(Box::new(ListNode { + val: -1, + next: None, + })); + let mut cur = &mut result_head; + let mut l1 = l1; + let mut l2 = l2; + let mut next = true; + while l1.is_some() || l2.is_some() { + //take去除值,并保留为None + match (l1.take(), l2.take()) { + (Some(_l1), None) => { + //可变引用 + if let Some(ref mut _cur) = cur { + _cur.next = Some(_l1); + } + } + (None, Some(_l2)) => { + if let Some(ref mut _cur) = cur { + _cur.next = Some(_l2); + } + } + (Some(mut _l1), Some(mut _l2)) => { + if &_l1.val < &_l2.val { + let _next = _l1.next.take(); + if let Some(ref mut _cur) = cur { + //将l1拼接到cur后面 + _cur.next = Some(_l1); + //移动cur本身 + cur = &mut _cur.next; + } + //移动链表l1,并将l2恢复 + l1 = _next; + l2 = Some(_l2); + } else { + let _next = _l2.next.take(); + if let Some(ref mut _cur) = cur { + _cur.next = Some(_l2); + cur = &mut _cur.next; + } + l2 = _next; + l1 = Some(_l1); + } + } + (None, None) => {} + } + } + return result_head.unwrap().next; + } +} diff --git a/rust-leetcode/src/interview_27.rs b/rust-leetcode/src/interview_27.rs new file mode 100644 index 00000000..eb3e2990 --- /dev/null +++ b/rust-leetcode/src/interview_27.rs @@ -0,0 +1,27 @@ +use std::borrow::{Borrow, BorrowMut}; +use std::cell::RefCell; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///二叉树的镜像 +impl Solution { + pub fn mirror_tree(root: Option>>) -> Option>> { + fn mirror(root: &mut Option>>) { + if let Some(node) = root { + let mut n = node.borrow_mut(); + unsafe { + //FUCK YOU + let lt = std::mem::replace(&mut (*n.as_ptr()).left, None); + let rt = std::mem::replace(&mut (*n.as_ptr()).right, lt); + std::mem::replace(&mut (*n.as_ptr()).left, rt); + mirror(&mut (*n.as_ptr()).right); + mirror(&mut (*n.as_ptr()).left); + } + } + } + let mut root = root; + mirror(&mut root); + root + } +} diff --git a/rust-leetcode/src/interview_32_2.rs b/rust-leetcode/src/interview_32_2.rs new file mode 100644 index 00000000..ea7402db --- /dev/null +++ b/rust-leetcode/src/interview_32_2.rs @@ -0,0 +1,45 @@ +use std::borrow::Borrow; +use std::cell::RefCell; +use std::collections::VecDeque; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///从上到下打印二叉树 II +impl Solution { + //leetcode 102 + pub fn level_order(root: Option>>) -> Vec> { + let mut ret = Vec::new(); + let mut nodes = VecDeque::new(); + let mut row = Vec::new(); + let mut flag = root.clone(); + nodes.push_back(root.clone()); + while !nodes.is_empty() { + let tmp = nodes.pop_front(); + if let Some(node) = tmp { + if let Some(n) = node { + row.push(n.try_borrow().unwrap().val); + if n.try_borrow().unwrap().left.is_some() { + nodes.push_back(n.try_borrow().unwrap().left.clone()); + } + if n.try_borrow().unwrap().right.is_some() { + nodes.push_back(n.try_borrow().unwrap().right.clone()); + } + if let Some(f) = flag.borrow() { + if f.as_ptr() == n.as_ptr() { + //直接back导致as_ptr不等 + let tail = nodes.pop_back(); + if tail.is_some() { + flag = tail.clone().unwrap(); + nodes.push_back(tail.unwrap()); + } + ret.push(row); + row = Vec::new(); + } + } + } + } + } + ret + } +} diff --git a/rust-leetcode/src/interview_54.rs b/rust-leetcode/src/interview_54.rs new file mode 100644 index 00000000..28506736 --- /dev/null +++ b/rust-leetcode/src/interview_54.rs @@ -0,0 +1,28 @@ +use std::cell::RefCell; +use std::collections::VecDeque; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///二叉搜索树的第k大节点 +impl Solution { + pub fn kth_largest(root: Option>>, k: i32) -> i32 { + let mut ret = Vec::new(); + let mut nodes = VecDeque::new(); + let mut cur = root.clone(); + while cur.is_some() || !nodes.is_empty() { + while let Some(c) = cur { + nodes.push_back(Some(c.clone())); + cur = c.try_borrow().unwrap().left.clone(); + } + if let Some(n) = nodes.pop_back().unwrap() { + ret.push(n.try_borrow().unwrap().val); + cur = n.try_borrow().unwrap().right.clone(); + } + } + for e in ret.iter() { + println!("{}", e); + } + ret[(ret.len() - k as usize)] + } +} diff --git a/rust-leetcode/src/interview_55_1.rs b/rust-leetcode/src/interview_55_1.rs new file mode 100644 index 00000000..ba43fcba --- /dev/null +++ b/rust-leetcode/src/interview_55_1.rs @@ -0,0 +1,20 @@ +use std::cell::RefCell; +use std::cmp::max; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///二叉树的深度 = leetcode 104 +impl Solution { + pub fn max_depth(root: Option>>) -> i32 { + fn get_depth(root: &Option>>) -> i32 { + if let Some(root) = root { + let node = root.try_borrow().unwrap(); + return max(get_depth(&node.left), get_depth(&node.right)) + 1; + } else { + return 0; + } + } + get_depth(&root) + } +} diff --git a/rust-leetcode/src/interview_58_2.rs b/rust-leetcode/src/interview_58_2.rs new file mode 100644 index 00000000..5397c5ae --- /dev/null +++ b/rust-leetcode/src/interview_58_2.rs @@ -0,0 +1,11 @@ +use crate::pre_structs::Solution; + +///左旋转字符串 +impl Solution { + pub fn reverse_left_words(s: String, n: i32) -> String { + let mut s1 = String::from(&s[0..n as usize]); + let s2 = &s[n as usize..s.len()]; + s1.insert_str(0, s2); + s1.to_owned() + } +} diff --git a/rust-leetcode/src/leetcode_1021.rs b/rust-leetcode/src/leetcode_1021.rs new file mode 100644 index 00000000..36586992 --- /dev/null +++ b/rust-leetcode/src/leetcode_1021.rs @@ -0,0 +1,43 @@ +use std::collections::VecDeque; + +use crate::pre_structs::Solution; + +///删除最外层的括号 +impl Solution { + pub fn remove_outer_parentheses(s: String) -> String { + let mut ret_str = String::new(); + let mut le = 0; + for c in s.chars() { + if c == ')' { + le -= 1 + } + if le >= 1 { + ret_str.push(c) + } + if c == '(' { + le += 1 + } + } + ret_str + } + + pub fn remove_outer_parentheses2(s: String) -> String { + let mut stack = VecDeque::new(); + let mut ret_str = String::new(); + for c in s.chars() { + //括号匹配,忽略最左边和最右边的括号 + if c == '(' { + stack.push_back(c); + if stack.len() > 1 { + ret_str.push(c); + } + } else { + stack.pop_back(); + if stack.len() != 0 { + ret_str.push(c); + } + } + } + ret_str + } +} diff --git a/rust-leetcode/src/leetcode_1051.rs b/rust-leetcode/src/leetcode_1051.rs new file mode 100644 index 00000000..8c548e55 --- /dev/null +++ b/rust-leetcode/src/leetcode_1051.rs @@ -0,0 +1,17 @@ +use crate::pre_structs::Solution; + +///高度检查器 +impl Solution { + pub fn height_checker(heights: Vec) -> i32 { + //排序后与原数组的差异个数 + let mut c_heights = heights.clone(); + let mut ret = 0; + c_heights.sort(); + for i in 0..heights.len() { + if c_heights[i as usize] != heights[i as usize] { + ret += 1; + } + } + ret + } +} diff --git a/rust-leetcode/src/leetcode_108.rs b/rust-leetcode/src/leetcode_108.rs new file mode 100644 index 00000000..0fa99317 --- /dev/null +++ b/rust-leetcode/src/leetcode_108.rs @@ -0,0 +1,22 @@ +use std::cell::RefCell; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///将有序数组转换为二叉搜索树 +impl Solution { + //与最小高度树 interview_04_02 一样 + pub fn sorted_array_to_bst2(nums: Vec) -> Option>> { + fn buildTree(nums: &Vec, l: i32, r: i32) -> Option>> { + if l > r { + return None; + } + let mid = l + (r - l) / 2; + let mut root = TreeNode::new(nums[mid as usize]); + root.left = buildTree(nums, l, mid - 1); + root.right = buildTree(nums, mid + 1, r); + return Some(Rc::new(RefCell::new(root))); + } + buildTree(&nums, 0, nums.len() as i32) + } +} diff --git a/rust-leetcode/src/leetcode_1160.rs b/rust-leetcode/src/leetcode_1160.rs new file mode 100644 index 00000000..45d8e201 --- /dev/null +++ b/rust-leetcode/src/leetcode_1160.rs @@ -0,0 +1,31 @@ +use crate::pre_structs::Solution; + +///拼写单词 +impl Solution { + pub fn count_characters(words: Vec, chars: String) -> i32 { + let mut char_count = vec![0; 'z' as usize + 1]; + for c in chars.chars() { + char_count[c as usize] += 1; + } + let mut ret = 0; + for word in words.iter() { + let mut word_count = vec![0; 'z' as usize + 1]; + for c in word.chars() { + word_count[c as usize] += 1; + } + let mut flg = true; + if word + .chars() + .map(|tc| -> bool { char_count[tc as usize] < word_count[tc as usize] }) + .find(|&x| x == true) + .is_some() + { + flg = false; + } + if flg { + ret += word.len() + } + } + ret as i32 + } +} diff --git a/rust-leetcode/src/leetcode_1207.rs b/rust-leetcode/src/leetcode_1207.rs new file mode 100644 index 00000000..54b91a29 --- /dev/null +++ b/rust-leetcode/src/leetcode_1207.rs @@ -0,0 +1,32 @@ +use std::collections::{HashMap, HashSet}; + +use crate::pre_structs::Solution; + +///独一无二的出现次数 +impl Solution { + pub fn unique_occurrences(arr: Vec) -> bool { + let mut map = HashMap::new(); + for num in arr.iter() { + let n = if map.contains_key(num) { + map.get(num).unwrap() + } else { + &0 + }; + if map.contains_key(num) { + map.insert(num, *n + 1); + } else { + map.insert(num, 1); + } + } + let set: HashSet = map.values().cloned().collect(); + set.len() == map.len() + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn unique_occurrences() {} +} diff --git a/rust-leetcode/src/leetcode_1221.rs b/rust-leetcode/src/leetcode_1221.rs new file mode 100644 index 00000000..b79cf103 --- /dev/null +++ b/rust-leetcode/src/leetcode_1221.rs @@ -0,0 +1,31 @@ +use crate::pre_structs::Solution; + +///分割平衡字符串 +impl Solution { + pub fn balanced_string_split(s: String) -> i32 { + let mut l = 0; + let mut ret = 0; + for c in s.chars() { + if c == 'L' { + l += 1; + } + if c == 'R' { + l -= 1; + } + if l == 0 { + ret += 1; + } + } + ret + } + //函数式 + pub fn balanced_string_split2(s: String) -> i32 { + s.chars() + .scan(0, |acc, e| { + *acc = if let 'R' = e { (*acc + 1) } else { (*acc - 1) }; + Some(*acc) + }) + .filter(|&e| e == 0) + .count() as i32 + } +} diff --git a/rust-leetcode/src/leetcode_1252.rs b/rust-leetcode/src/leetcode_1252.rs new file mode 100644 index 00000000..403da930 --- /dev/null +++ b/rust-leetcode/src/leetcode_1252.rs @@ -0,0 +1,25 @@ +use crate::pre_structs::Solution; + +///奇数值单元格的数目 +impl Solution { + pub fn odd_cells(n: i32, m: i32, indices: Vec>) -> i32 { + let mut arr = vec![vec![0; m as usize]; n as usize]; + let mut res = 0; + for row in indices { + for i in 0..n { + arr[i as usize][row[1] as usize] += 1; + } + for j in 0..m { + arr[row[0] as usize][j as usize] += 1; + } + } + for i in 0..n { + for j in 0..m { + if arr[i as usize][j as usize] & 1 == 1 { + res += 1; + } + } + } + res + } +} diff --git a/rust-leetcode/src/leetcode_1281.rs b/rust-leetcode/src/leetcode_1281.rs new file mode 100644 index 00000000..8876446c --- /dev/null +++ b/rust-leetcode/src/leetcode_1281.rs @@ -0,0 +1,17 @@ +use crate::pre_structs::Solution; + +///整数的各位积和之差 +impl Solution { + pub fn subtract_product_and_sum(n: i32) -> i32 { + let mut num = n; + let mut muti = 1; + let mut sum = 0; + while num != 0 { + let mut tmp = num % 10; + muti *= tmp; + sum += tmp; + num /= 10; + } + muti - sum + } +} diff --git a/rust-leetcode/src/leetcode_13.rs b/rust-leetcode/src/leetcode_13.rs new file mode 100644 index 00000000..a506064f --- /dev/null +++ b/rust-leetcode/src/leetcode_13.rs @@ -0,0 +1,87 @@ +use std::collections::HashMap; +use std::ops::Index; + +use crate::pre_structs::Solution; + +///罗马数字转整数 +impl Solution { + pub fn roman_to_int(s: String) -> i32 { + let mut maps = HashMap::new(); + let chs = vec!["I", "V", "X", "L", "C", "D", "M"]; + let n = vec![1, 5, 10, 50, 100, 500, 1000]; + let mut ret = 0; + let right = s.len() - 1; + n.iter().enumerate().for_each(|(x, &y)| { + maps.insert(chs[x], y); + }); + for i in 0..right { + //字不是顺序的,但是数字列表是顺序的 + if maps[s.index(i..=i)] >= maps[s.index(i + 1..=i + 1)] { + ret += maps[s.index(i..=i)]; + } else { + ret -= maps[s.index(i..=i)]; + } + } + ret += maps[s.index(right..=right)]; + ret + } + + //Legend Lee + pub fn roman_to_int2(s: String) -> i32 { + fn roman_to_int_char(c: char) -> Option { + match c { + 'I' => Some(1), + 'V' => Some(5), + 'X' => Some(10), + 'L' => Some(50), + 'C' => Some(100), + 'D' => Some(500), + 'M' => Some(1000), + _ => None, + } + } + + let mut v = 0i32; + if s.is_empty() { + return 0; + } + + s.chars() + .zip(s.chars().skip(1)) + .for_each(|(first, second)| { + let a = roman_to_int_char(first).unwrap(); + let b = roman_to_int_char(second).unwrap(); + v += (if a < b { -1 * a } else { a }); + }); + v += roman_to_int_char(s.chars().last().unwrap()).unwrap(); + + v + } + + //闲杂织造 + pub fn roman_to_int3(s: String) -> i32 { + let tr = vec![ + ('I', 1), + ('V', 5), + ('X', 10), + ('L', 50), + ('C', 100), + ('D', 500), + ('M', 1000), + ]; + let mut hash: HashMap = tr.iter().cloned().collect(); + let chars: Vec = s.chars().collect(); + let mut ans = 0; + let n = chars.len(); + for i in 0..n - 1 { + let cc = hash[&chars[i]]; + let nc = hash[&chars[i + 1]]; + if cc < nc { + ans -= cc; + } else { + ans += cc; + } + } + ans + hash[&chars[n - 1]] + } +} diff --git a/rust-leetcode/src/leetcode_1304.rs b/rust-leetcode/src/leetcode_1304.rs new file mode 100644 index 00000000..f409500a --- /dev/null +++ b/rust-leetcode/src/leetcode_1304.rs @@ -0,0 +1,36 @@ +use crate::pre_structs::Solution; + +///和为零的N个唯一整数 +impl Solution { + //双指针 + pub fn sum_zero(n: i32) -> Vec { + let mut ret = vec![0; n as usize]; + let mut i = 0usize; + let mut j = (n - 1) as usize; + let mut c = 1; + loop { + if i >= j { + break; + } + ret[i] = c; + ret[j] = -c; + i += 1; + j -= 1; + c += 1; + } + ret + } + + pub fn sum_zero2(n: i32) -> Vec { + let mut ret = vec![0; n as usize]; + let mut sum = 0; + let mut j = 0; + for i in 0..=n - 2 { + ret[j] = i; + j += 1; + sum += i; + } + ret[(n - 1) as usize] = -sum; + ret + } +} diff --git a/rust-leetcode/src/leetcode_1313.rs b/rust-leetcode/src/leetcode_1313.rs new file mode 100644 index 00000000..32880819 --- /dev/null +++ b/rust-leetcode/src/leetcode_1313.rs @@ -0,0 +1,19 @@ +use crate::pre_structs::Solution; + +///解压缩编码列表 +impl Solution { + pub fn decompress_rl_elist(nums: Vec) -> Vec { + let mut rets = Vec::new(); + for (index, e) in nums.iter().enumerate() { + if index & 1 == 0 { + let mut freq = nums[index]; + let value = nums[index + 1]; + while freq != 0 { + rets.push(value); + freq -= 1; + } + } + } + rets + } +} diff --git a/rust-leetcode/src/leetcode_1323.rs b/rust-leetcode/src/leetcode_1323.rs new file mode 100644 index 00000000..9dc7a01c --- /dev/null +++ b/rust-leetcode/src/leetcode_1323.rs @@ -0,0 +1,8 @@ +use crate::pre_structs::Solution; + +///6 和 9 组成的最大数字 +impl Solution { + pub fn maximum69_number(num: i32) -> i32 { + num.to_string().replacen('6', "9", 1).parse().unwrap() + } +} diff --git a/rust-leetcode/src/leetcode_1342.rs b/rust-leetcode/src/leetcode_1342.rs new file mode 100644 index 00000000..2c4b06bc --- /dev/null +++ b/rust-leetcode/src/leetcode_1342.rs @@ -0,0 +1,18 @@ +use crate::pre_structs::Solution; + +///将数字变成 0 的操作次数 +impl Solution { + pub fn number_of_steps(num: i32) -> i32 { + let mut n = num; + let mut i = 0; + while n != 0 { + if n & 1 == 0 { + n /= 2; + } else { + n -= 1; + } + i += 1; + } + i + } +} diff --git a/rust-leetcode/src/leetcode_1351.rs b/rust-leetcode/src/leetcode_1351.rs new file mode 100644 index 00000000..924db408 --- /dev/null +++ b/rust-leetcode/src/leetcode_1351.rs @@ -0,0 +1,13 @@ +use crate::pre_structs::Solution; + +///统计有序矩阵中的负数 +impl Solution { + //应该将矩阵是排序的考虑进去,从右下角或左下角使用标记 + pub fn count_negatives(grid: Vec>) -> i32 { + let mut count: i32 = 0; + for r in grid.iter() { + count += r.iter().filter(|&&x| x < 0).count() as i32 + } + return count; + } +} diff --git a/rust-leetcode/src/leetcode_1365.rs b/rust-leetcode/src/leetcode_1365.rs new file mode 100644 index 00000000..28c5def9 --- /dev/null +++ b/rust-leetcode/src/leetcode_1365.rs @@ -0,0 +1,18 @@ +use crate::pre_structs::Solution; + +///有多少小于当前数字的数字 +impl Solution { + pub fn smaller_numbers_than_current(nums: Vec) -> Vec { + let mut ret = Vec::with_capacity(nums.len()); + for i in 0..nums.len() { + let mut count = 0; + for j in 0..nums.len() { + if nums[i] > nums[j] { + count += 1; + } + } + ret.push(count); + } + ret + } +} diff --git a/rust-leetcode/src/leetcode_1370.rs b/rust-leetcode/src/leetcode_1370.rs new file mode 100644 index 00000000..0eed9608 --- /dev/null +++ b/rust-leetcode/src/leetcode_1370.rs @@ -0,0 +1,27 @@ +use crate::pre_structs::Solution; + +///上升下降字符串 +impl Solution { + pub fn sort_string(s: String) -> String { + let mut ret = String::new(); + let mut v = vec![0; 26]; + for c in s.chars() { + v[c as usize - 97] += 1; + } + while ret.len() < s.len() { + for n in 0..26u8 { + if v[n as usize] > 0 { + ret.push((n + 97) as char); + v[n as usize] -= 1; + } + } + for n in (0..=25u8).rev() { + if v[n as usize] > 0 { + ret.push((n + 97) as char); + v[n as usize] -= 1; + } + } + } + ret + } +} diff --git a/rust-leetcode/src/leetcode_1374.rs b/rust-leetcode/src/leetcode_1374.rs new file mode 100644 index 00000000..83af2f8b --- /dev/null +++ b/rust-leetcode/src/leetcode_1374.rs @@ -0,0 +1,18 @@ +use crate::pre_structs::Solution; + +///生成每种字符都是奇数个的字符串 +impl Solution { + //偷鸡 + pub fn generate_the_string(n: i32) -> String { + let mut ret = vec![]; + if n & 1 == 0 { + ret = vec!['a'; (n - 1) as usize]; + ret.push('b'); + } else { + ret = vec!['a'; n as usize]; + } + let mut rs = String::new(); + ret.iter().for_each(|&c| rs.push(c)); + rs + } +} diff --git a/rust-leetcode/src/leetcode_1380.rs b/rust-leetcode/src/leetcode_1380.rs new file mode 100644 index 00000000..e756b37b --- /dev/null +++ b/rust-leetcode/src/leetcode_1380.rs @@ -0,0 +1,32 @@ +use std::cmp::max; +use std::cmp::min; + +use crate::pre_structs::Solution; + +///矩阵中的幸运数 +impl Solution { + //min数组存放每行最小值;man数组存放每列最大值; + //得到每一行的最小值和每一列的最大值。(行或列上的最大最小值) + //然后比较第i行最小值和第j列最大值是否为同一个数,即min[i] == max[j] + pub fn lucky_numbers(matrix: Vec>) -> Vec { + let m = matrix.len(); + let n = matrix[0].len(); + let mut min_t = vec![i32::max_value(); m]; + let mut max_t = vec![i32::min_value(); n]; + for i in 0..m { + for j in 0..n { + min_t[i] = min(min_t[i], matrix[i][j]); + max_t[j] = max(max_t[j], matrix[i][j]); + } + } + let mut result = Vec::new(); + for i in 0..m { + for j in 0..n { + if min_t[i] == max_t[j] { + result.push(min_t[i]); + } + } + } + result + } +} diff --git a/rust-leetcode/src/leetcode_1385.rs b/rust-leetcode/src/leetcode_1385.rs new file mode 100644 index 00000000..ba666282 --- /dev/null +++ b/rust-leetcode/src/leetcode_1385.rs @@ -0,0 +1,22 @@ +use crate::pre_structs::Solution; + +///两个数组间的距离值 +impl Solution { + //暴力解 + pub fn find_the_distance_value(arr1: Vec, arr2: Vec, d: i32) -> i32 { + let mut c = 0; + let ret = arr1.iter().for_each(|&x| { + let mut flag = false; + arr2.iter().for_each(|&y| { + if !flag && (x - y).abs() > d { + } else { + flag = true; + } + }); + if !flag { + c += 1; + } + }); + c + } +} diff --git a/rust-leetcode/src/leetcode_14.rs b/rust-leetcode/src/leetcode_14.rs new file mode 100644 index 00000000..55b6b4d4 --- /dev/null +++ b/rust-leetcode/src/leetcode_14.rs @@ -0,0 +1,79 @@ +use crate::pre_structs::Solution; + +///最长公共前缀 +impl Solution { + //0 ms, 2.1 MB + pub fn longest_common_prefix(strs: Vec) -> String { + //选出最小的字符串w,使用w的所有子串去匹配strs中的单词 + let mut min_word: &String = &"".to_owned(); + let mut min_length = usize::max_value(); + if strs.is_empty() { + return min_word.clone(); + } + let mut result: &str = ""; + strs.iter().for_each(|word| { + if min_length > word.len() { + min_length = word.len(); + min_word = word; + } + }); + while min_length > 0 { + let mut sub_word = &min_word[0..min_length]; + let mut is_max = true; + for w in strs.iter() { + if w.starts_with(sub_word) == false { + is_max = false; + break; + } + } + if is_max { + result = sub_word; + break; + } + min_length -= 1; + } + result.to_owned() + } + + //0 ms, 2.1 MB + pub fn longest_common_prefix2(strs: Vec) -> String { + let strs = &strs; + let mut result: String = "".to_owned(); + if strs.is_empty() { + return result; + } + //选取第一个单词w,对w的长度从大到小进行切片,将切片与所有单词进行匹配 + result = strs[0].clone(); + for (index, word) in strs.iter().enumerate() { + while !word.starts_with(result.as_str()) { + result = result[0..result.len() - 1].to_owned(); + if result.len() == 0 { + return "".to_owned(); + } + } + } + result + } + + //4 ms, 2.1 MB + pub fn longest_common_prefix3(strs: Vec) -> String { + let strs = &strs; + let mut result: String = "".to_owned(); + if strs.is_empty() { + return result; + } + //选取第一个单词w,与其他字符串依次比较对应位置上的字符 + let word = &strs[0].clone(); + let init_word: Vec = word.chars().collect(); + for i in 0..init_word.len() { + let mut c: char = init_word[i]; + for j in 1..strs.len() { + let cs: Vec = strs[j].chars().collect(); + if i < cs.len() && c != cs[i] || i == cs.len() { + return word[0..i].to_owned(); + } + } + } + word.to_owned() + } +} diff --git a/rust-leetcode/src/leetcode_1403.rs b/rust-leetcode/src/leetcode_1403.rs new file mode 100644 index 00000000..1218bbc8 --- /dev/null +++ b/rust-leetcode/src/leetcode_1403.rs @@ -0,0 +1,19 @@ +use crate::pre_structs::Solution; + +///非递增顺序的最小子序列 +impl Solution { + pub fn min_subsequence(nums: Vec) -> Vec { + let mut nums = nums; + nums.sort_by(|a, b| b.cmp(a)); + let size = nums.len(); + let mut f = 0; + let sum: i32 = nums.iter().sum(); + for i in 0..size { + f += nums[i]; + if f > sum - f { + return nums[..i + 1].to_vec(); + } + } + nums + } +} diff --git a/rust-leetcode/src/leetcode_1413.rs b/rust-leetcode/src/leetcode_1413.rs new file mode 100644 index 00000000..fe3eebba --- /dev/null +++ b/rust-leetcode/src/leetcode_1413.rs @@ -0,0 +1,20 @@ +use std::cmp::max; + +use crate::pre_structs::Solution; + +///逐步求和得到正数的最小值 +impl Solution { + pub fn min_start_value(nums: Vec) -> i32 { + let mut start = 1; + let mut min_sum = 0; + for &n in nums.iter() { + min_sum += n; + //累加和的最小值是正数 + //min_sum + x >= 1 + //x >= 1 - min_sum + //min(x) = 1 - min_sum + start = max(start, 1 - min_sum); + } + start + } +} diff --git a/rust-leetcode/src/leetcode_20.rs b/rust-leetcode/src/leetcode_20.rs new file mode 100644 index 00000000..4719ca1e --- /dev/null +++ b/rust-leetcode/src/leetcode_20.rs @@ -0,0 +1,28 @@ +use crate::pre_structs::Solution; + +///有效的括号 +impl Solution { + pub fn is_valid(s: String) -> bool { + let chars: Vec = s.chars().collect(); + let mut stack = Vec::::new(); + for &c in chars.iter() { + if c == '{' || c == '[' || c == '(' { + stack.push(c); + } else { + if stack.is_empty() { + return false; + } + let c_stack = stack.pop(); + if let Some(cStack) = c_stack { + if c == ')' && cStack != '(' + || c == ']' && cStack != '[' + || c == '}' && cStack != '{' + { + return false; + } + } + } + } + stack.is_empty() + } +} diff --git a/rust-leetcode/src/leetcode_292.rs b/rust-leetcode/src/leetcode_292.rs new file mode 100644 index 00000000..a5834b65 --- /dev/null +++ b/rust-leetcode/src/leetcode_292.rs @@ -0,0 +1,12 @@ +use crate::pre_structs::Solution; + +///Nim 游戏 +impl Solution { + pub fn can_win_nim(n: i32) -> bool { + if n % 4 == 0 { + false + } else { + true + } + } +} diff --git a/rust-leetcode/src/leetcode_35.rs b/rust-leetcode/src/leetcode_35.rs new file mode 100644 index 00000000..18b158a3 --- /dev/null +++ b/rust-leetcode/src/leetcode_35.rs @@ -0,0 +1,22 @@ +use crate::pre_structs::Solution; + +///搜索插入位置 +impl Solution { + pub fn search_insert(nums: Vec, target: i32) -> i32 { + let mut nums = nums; + //找到知己反回索引,没有找到则返回该元素插入后保持数组仍然有序的索引位置,主要用于有序的数组/向量 + let ret = match nums.binary_search(&target) { + Ok(found_index) => found_index, + Err(maybe_insert) => maybe_insert, + }; + ret as i32 + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn search_insert() {} +} diff --git a/rust-leetcode/src/leetcode_38.rs b/rust-leetcode/src/leetcode_38.rs new file mode 100644 index 00000000..44582f60 --- /dev/null +++ b/rust-leetcode/src/leetcode_38.rs @@ -0,0 +1,50 @@ +use crate::pre_structs::Solution; + +///外观数列 +impl Solution { + //给一个数,这个数是1 + //描述上一步的数,这个数是1即一个1,故写作11 + //描述上一步的数,这个数是11即两个1,故写作21 + //描述上一步的数,这个数是21即一个2一个1,故写作12-11 + //描述上一步的数,这个数是1211即一个1一个2两个1,故写作11-12-21 + pub fn count_and_say(n: i32) -> String { + if n == 1 { + return "1".to_owned(); + } + let pre_str = Solution::count_and_say(n - 1); + let mut curr_str = String::new(); + let mut pre_char = None; + let mut pre_char_count = 0; + //当n为2及以上时。因为下一个数列是对上面的解释。所以用三个变量,一个代表数量count ,一个代表前一个数字pre,一个代表后一个数字back + for back_char in pre_str.chars() { + if pre_char == None { + pre_char = Some(back_char); + } + if back_char != pre_char.unwrap() { + //将pre_char_count个pre_char分别存储 + curr_str.push_str(&pre_char_count.to_string()); + curr_str.push(pre_char.unwrap()); + pre_char = Some(back_char); + //不同时,重置个数 + pre_char_count = 1; + } else { + //相等时计算字符个数 + pre_char_count += 1; + } + } + //最后一位在前面跳出来了,需要追加 + if pre_char_count > 0 { + curr_str.push_str(&pre_char_count.to_string()); + curr_str.push(pre_char.unwrap()); + } + curr_str + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn count_and_say() {} +} diff --git a/rust-leetcode/src/leetcode_461.rs b/rust-leetcode/src/leetcode_461.rs new file mode 100644 index 00000000..fc1de683 --- /dev/null +++ b/rust-leetcode/src/leetcode_461.rs @@ -0,0 +1,17 @@ +use crate::pre_structs::Solution; + +///汉明距离 +impl Solution { + pub fn hamming_distance(x: i32, y: i32) -> i32 { + let mut nums = x ^ y; + //二进制中1的个数 + let mut c = 0; + while nums != 0 { + if nums & 1 == 1 { + c += 1; + } + nums = nums >> 1; + } + c + } +} diff --git a/rust-leetcode/src/leetcode_500.rs b/rust-leetcode/src/leetcode_500.rs new file mode 100644 index 00000000..e4158507 --- /dev/null +++ b/rust-leetcode/src/leetcode_500.rs @@ -0,0 +1,52 @@ +use std::collections::{HashMap, HashSet}; + +use crate::pre_structs::Solution; + +///键盘行 +impl Solution { + pub fn find_words(words: Vec) -> Vec { + let map: HashMap = vec![ + ('Q', 0), + ('W', 0), + ('E', 0), + ('R', 0), + ('T', 0), + ('Y', 0), + ('U', 0), + ('I', 0), + ('O', 0), + ('P', 0), + ('A', 1), + ('S', 1), + ('D', 1), + ('F', 1), + ('G', 1), + ('H', 1), + ('J', 1), + ('K', 1), + ('L', 1), + ('Z', 2), + ('X', 2), + ('C', 2), + ('V', 2), + ('B', 2), + ('N', 2), + ('M', 2), + ] + .iter() + .cloned() + .collect(); + words + .iter() + .filter(|word| { + let chars: Vec = word.chars().collect(); + let index: HashSet = chars + .iter() + .map(|c| -> i32 { map[&c.to_ascii_uppercase()] }) + .collect(); + index.len() == 1 + }) + .cloned() + .collect() + } +} diff --git a/rust-leetcode/src/leetcode_557.rs b/rust-leetcode/src/leetcode_557.rs new file mode 100644 index 00000000..e6a2e67f --- /dev/null +++ b/rust-leetcode/src/leetcode_557.rs @@ -0,0 +1,16 @@ +use crate::pre_structs::Solution; + +///反转字符串中的单词 III +impl Solution { + pub fn reverse_words(s: String) -> String { + let arr: Vec<&str> = s.split(' ').collect(); + let ret: Vec = arr + .iter() + .map(|word| -> String { + let c: String = (*word).chars().rev().collect(); + c + }) + .collect(); + ret.join(" ").to_string() + } +} diff --git a/rust-leetcode/src/leetcode_561.rs b/rust-leetcode/src/leetcode_561.rs new file mode 100644 index 00000000..031e6e7c --- /dev/null +++ b/rust-leetcode/src/leetcode_561.rs @@ -0,0 +1,17 @@ +use crate::pre_structs::Solution; + +///数组拆分 I +impl Solution { + //尽可能保留最大值 + pub fn array_pair_sum(nums: Vec) -> i32 { + let mut nums = nums; + nums.sort(); + let mut sum = 0; + let mut i = 0; + while i < nums.len() { + sum += nums[i as usize]; + i += 2; + } + sum + } +} diff --git a/rust-leetcode/src/leetcode_58.rs b/rust-leetcode/src/leetcode_58.rs new file mode 100644 index 00000000..abda959a --- /dev/null +++ b/rust-leetcode/src/leetcode_58.rs @@ -0,0 +1,17 @@ +use crate::pre_structs::Solution; + +///最后一个单词的长度 +impl Solution { + pub fn length_of_last_word(s: String) -> i32 { + let chars: Vec<&str> = s.trim().split(' ').collect(); + chars[chars.len() - 1].len() as i32 + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn length_of_last_word() {} +} diff --git a/rust-leetcode/src/leetcode_617.rs b/rust-leetcode/src/leetcode_617.rs new file mode 100644 index 00000000..369ca621 --- /dev/null +++ b/rust-leetcode/src/leetcode_617.rs @@ -0,0 +1,65 @@ +use std::borrow::{Borrow, BorrowMut}; +use std::cell::RefCell; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///合并二叉树 +impl Solution { + ///author 李广胜 + pub fn merge_trees( + t1: Option>>, + t2: Option>>, + ) -> Option>> { + if t1.is_none() { + return t2; + } + if t2.is_none() { + return t1; + } + let b1: Rc> = t1.unwrap(); + let b1: &RefCell = b1.borrow(); + let b2: Rc> = t2.unwrap(); + let b2: &RefCell = b2.borrow(); + unsafe { + //直接b2.val编译错误 + Some(Rc::new(RefCell::new(TreeNode { + val: (*b1.as_ptr()).val + (*b2.as_ptr()).val, + left: Solution::merge_trees( + (*b1.as_ptr()).left.clone(), + (*b2.as_ptr()).left.clone(), + ), + right: Solution::merge_trees( + (*b1.as_ptr()).right.clone(), + (*b2.as_ptr()).right.clone(), + ), + }))) + } + } + + ///author 长条人 + pub fn merge_trees2( + t1: Option>>, + t2: Option>>, + ) -> Option>> { + fn merge(t1: &mut Option>>, t2: &Option>>) { + if let Some(mut n1) = t1.as_ref() { + if let Some(n2) = t2 { + let mut n1 = n1.borrow_mut(); + let n2: &RefCell = n2.borrow(); + unsafe { + (*n1.as_ptr()).val += (*n2.as_ptr()).val; + merge(&mut (*n1.as_ptr()).left, &(*n2.as_ptr()).left); + merge(&mut (*n1.as_ptr()).right, &(*n2.as_ptr()).right); + } + } else { + } + } else { + *t1 = t2.clone(); + } + } + let mut t1 = t1; + merge(&mut t1, &t2); + t1 + } +} diff --git a/rust-leetcode/src/leetcode_665.rs b/rust-leetcode/src/leetcode_665.rs new file mode 100644 index 00000000..a39ec722 --- /dev/null +++ b/rust-leetcode/src/leetcode_665.rs @@ -0,0 +1,40 @@ +use crate::pre_structs::Solution; + +///非递减数列 +impl Solution { + pub fn check_possibility(nums: Vec) -> bool { + let mut nums = nums; + let mut cnt = 0; + if nums.len() < 2 { + return true; + } + //将局部调整为最优方案 + //当 i 和 i+1 构成逆序时 + for i in 0..nums.len() - 1 { + if nums[i] > nums[i + 1] { + if i == 0 || nums[i - 1] <= nums[i + 1] { + //如果 i-1 和 i+1 是升序排列,此时缩小 i 的值 + nums[i] = nums[i + 1]; + } else if nums[i - 1] > nums[i + 1] { + //如果 i-1 和 i+1 是降序排列,此时增大 i+1 的值 + nums[i + 1] = nums[i]; + } else { + } + //计算需要改动的次数 + cnt += 1; + if cnt > 1 { + return false; + } + } + } + true + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn check_possibility() {} +} diff --git a/rust-leetcode/src/leetcode_709.rs b/rust-leetcode/src/leetcode_709.rs new file mode 100644 index 00000000..fb4bfa0e --- /dev/null +++ b/rust-leetcode/src/leetcode_709.rs @@ -0,0 +1,17 @@ +use crate::pre_structs::Solution; + +///转换成小写字母 +impl Solution { + pub fn to_lower_case(str: String) -> String { + str.chars() + .map(|c| { + //说明是大写,+32 + if c < 'a' && c >= 'A' { + (c as u8 + 32 as u8) as char + } else { + c + } + }) + .collect() + } +} diff --git a/rust-leetcode/src/leetcode_728.rs b/rust-leetcode/src/leetcode_728.rs new file mode 100644 index 00000000..066baddb --- /dev/null +++ b/rust-leetcode/src/leetcode_728.rs @@ -0,0 +1,24 @@ +use crate::pre_structs::Solution; + +///自除数 +impl Solution { + pub fn self_dividing_numbers(left: i32, right: i32) -> Vec { + let mut result = Vec::new(); + for num in left..=right { + if helper(num) { + result.push(num) + } + } + + fn helper(n: i32) -> bool { + for c in n.to_string().chars() { + if ((c as i32) - 48) == 0 || n % ((c as i32) - 48) != 0 { + return false; + } + } + return true; + } + + result + } +} diff --git a/rust-leetcode/src/leetcode_804.rs b/rust-leetcode/src/leetcode_804.rs new file mode 100644 index 00000000..e21ff4bd --- /dev/null +++ b/rust-leetcode/src/leetcode_804.rs @@ -0,0 +1,25 @@ +use std::collections::HashSet; + +use crate::pre_structs::Solution; + +///唯一摩尔斯密码词 +impl Solution { + pub fn unique_morse_representations(words: Vec) -> i32 { + let m = vec![ + ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", + "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", + "-.--", "--..", + ]; + let mut ret = HashSet::new(); + for w in words.iter() { + let mut mw = String::new(); + for c in w.chars() { + //bad smell + let c = m[(c as u8 - 97) as usize]; + mw.push_str(c); + } + ret.insert(mw); + } + ret.len() as i32 + } +} diff --git a/rust-leetcode/src/leetcode_832.rs b/rust-leetcode/src/leetcode_832.rs new file mode 100644 index 00000000..067b82c5 --- /dev/null +++ b/rust-leetcode/src/leetcode_832.rs @@ -0,0 +1,22 @@ +use crate::pre_structs::Solution; + +///翻转图像 +impl Solution { + pub fn flip_and_invert_image(a: Vec>) -> Vec> { + let ret: Vec> = a + .iter() + .map(|mut row| -> Vec { + let mut new_row: Vec = row + .iter() + .map(|x| -> i32 { + let new_x = if let 0 = x { 1 } else { 0 }; + new_x + }) + .collect(); + new_row.reverse(); + new_row + }) + .collect(); + ret + } +} diff --git a/rust-leetcode/src/leetcode_859.rs b/rust-leetcode/src/leetcode_859.rs new file mode 100644 index 00000000..513440f0 --- /dev/null +++ b/rust-leetcode/src/leetcode_859.rs @@ -0,0 +1,58 @@ +use std::collections::HashSet; + +use crate::pre_structs::Solution; + +///新代码使用rust自带的单测 +///859. 亲密字符串 +impl Solution { + pub fn buddy_strings(a: String, b: String) -> bool { + let mut vect: Vec = Vec::new(); + if a.len() != b.len() { + return false; + } + let mut tmp = HashSet::new(); + if a == b { + let cs: Vec = a.chars().collect(); + cs.iter().for_each(|c| { + tmp.insert(c); + }); + + //有重复元素 + if tmp.len() < a.len() { + return true; + } else { + return false; + } + } + + for i in 0..a.len() { + //不同的字符的下标进数组 + if a[i..=i] != b[i..=i] { + vect.push(i); + } + } + //不同的字符的下标数超过两个 + if vect.len() != 2 { + return false; + } + + if (a[vect[0]..=vect[0]] != b[vect[1]..=vect[1]]) + || (a[vect[1]..=vect[1]] != b[vect[0]..=vect[0]]) + { + return false; + } + + return true; + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn buddy_strings() { + assert!(Solution::buddy_strings("ab".to_owned(), "ba".to_owned())); + assert!(!Solution::buddy_strings("ab".to_owned(), "ab".to_owned())); + } +} diff --git a/rust-leetcode/src/leetcode_876.rs b/rust-leetcode/src/leetcode_876.rs new file mode 100644 index 00000000..3f55831e --- /dev/null +++ b/rust-leetcode/src/leetcode_876.rs @@ -0,0 +1,14 @@ +use crate::pre_structs::{ListNode, Solution}; + +///链表的中间结点 +impl Solution { + pub fn middle_node(head: Option>) -> Option> { + let mut q = &head; + let mut s = &head; + while q.is_some() && q.as_ref().unwrap().next.is_some() { + q = &q.as_ref().unwrap().next.as_ref().unwrap().next; + s = &s.as_ref().unwrap().next; + } + s.clone() + } +} diff --git a/rust-leetcode/src/leetcode_9.rs b/rust-leetcode/src/leetcode_9.rs new file mode 100644 index 00000000..57b6d062 --- /dev/null +++ b/rust-leetcode/src/leetcode_9.rs @@ -0,0 +1,39 @@ +use std::ops::Index; + +use crate::pre_structs::Solution; + +///回文数 +impl Solution { + //1.双指针,2.找规律,3.字符串,4.栈 + pub fn is_palindrome(x: i32) -> bool { + //4ms + let mut n = x; + if n < 0 || (n != 0 && n % 10 == 0) { + return false; + } else { + let mut tmp = 0; + while n > 0 { + tmp = tmp * 10 + (n % 10); + n /= 10; + } + return tmp == x; + } + } + + pub fn is_palindrome2(x: i32) -> bool { + //直接to_string后index需要8ms + //let mut nums: Vec = x.to_string().chars().map(|x| x.to_owned() ).collect(); + //nums[i] != nums[j] 需要16ms + let mut nums = x.to_string(); + let mut i = 0; + let mut j = nums.len() - 1; + while i < j { + if nums.index(i..=i) != nums.index(j..=j) { + return false; + } + i += 1; + j -= 1; + } + true + } +} diff --git a/rust-leetcode/src/leetcode_905.rs b/rust-leetcode/src/leetcode_905.rs new file mode 100644 index 00000000..82da36fa --- /dev/null +++ b/rust-leetcode/src/leetcode_905.rs @@ -0,0 +1,18 @@ +use crate::pre_structs::Solution; + +///按奇偶排序数组 +impl Solution { + pub fn sort_array_by_parity(a: Vec) -> Vec { + let (mut even, mut odd): (Vec, Vec) = a.iter().partition(|&n| n % 2 == 0); + even.append(&mut odd); + even + } +} + +#[cfg(test)] +mod test { + use crate::pre_structs::Solution; + + #[test] + fn sort_array_by_parity() {} +} diff --git a/rust-leetcode/src/leetcode_933.rs b/rust-leetcode/src/leetcode_933.rs new file mode 100644 index 00000000..fc9926d4 --- /dev/null +++ b/rust-leetcode/src/leetcode_933.rs @@ -0,0 +1,26 @@ +use std::collections::VecDeque; + +///最近的请求次数 +struct RecentCounter { + queue: VecDeque, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl RecentCounter { + fn new() -> Self { + RecentCounter { + queue: VecDeque::new(), + } + } + + fn ping(&mut self, t: i32) -> i32 { + self.queue.push_back(t); + while *self.queue.front().unwrap() < t - 3000 { + self.queue.pop_front(); + } + self.queue.len() as i32 + } +} diff --git a/rust-leetcode/src/leetcode_938.rs b/rust-leetcode/src/leetcode_938.rs new file mode 100644 index 00000000..a0591357 --- /dev/null +++ b/rust-leetcode/src/leetcode_938.rs @@ -0,0 +1,52 @@ +use std::cell::RefCell; +use std::collections::VecDeque; +use std::rc::Rc; + +use crate::pre_structs::{Solution, TreeNode}; + +///二叉搜索树的范围和 +impl Solution { + pub fn range_sum_bst(root: Option>>, l: i32, r: i32) -> i32 { + let mut ret = 0; + let mut nodes = VecDeque::new(); + nodes.push_back(root); + while !nodes.is_empty() { + let tmp = nodes.pop_back(); + if let Some(node) = tmp { + if let Some(n) = node { + if n.try_borrow().unwrap().val >= l && n.try_borrow().unwrap().val <= r { + ret += n.try_borrow().unwrap().val + } + //满足条件继续查找 + if n.try_borrow().unwrap().val > l { + nodes.push_back(n.try_borrow().unwrap().left.clone()); + } + if n.try_borrow().unwrap().val < r { + nodes.push_back(n.try_borrow().unwrap().right.clone()); + } + } + } + } + ret + } + + pub fn range_sum_bst2(root: Option>>, l: i32, r: i32) -> i32 { + let mut ret = 0; + fn bst(root: Option>>, l: i32, r: i32, ret: &mut i32) { + if let Some(node) = root { + if node.try_borrow().unwrap().val >= l && node.try_borrow().unwrap().val <= r { + *ret += node.try_borrow().unwrap().val + } + if node.try_borrow().unwrap().val > l { + bst(node.try_borrow().unwrap().left.clone(), l, r, ret) + } + if node.try_borrow().unwrap().val < r { + bst(node.try_borrow().unwrap().right.clone(), l, r, ret) + } + } + } + //可变借用,修改外函数的变量ret + bst(root, l, r, &mut ret); + ret + } +} diff --git a/rust-leetcode/src/leetcode_942.rs b/rust-leetcode/src/leetcode_942.rs new file mode 100644 index 00000000..33f5c0d7 --- /dev/null +++ b/rust-leetcode/src/leetcode_942.rs @@ -0,0 +1,24 @@ +use crate::pre_structs::Solution; + +///增减字符串匹配 +impl Solution { + pub fn di_string_match(s: String) -> Vec { + let n = s.len(); + //'D'代表着倒序,'I'代表升序,那么如果为'D',只要取最大值max,同时最大值减一,作为下一个'D'的最大值;如果为'I',则正好相反,取最小值min,同时加一, + //作为下一个'I'的最小值;剩下最后一个值,max=min,取啥都行 + let mut arr = vec![0; n + 1]; + let mut max = n as i32; + let mut min = 0; + for i in 0..n { + if s.get(i..=i).unwrap() == "D" { + arr[i] = max; + max -= 1; + } else { + arr[i] = min; + min += 1; + } + } + arr[n] = max; + arr + } +} diff --git a/rust-leetcode/src/leetcode_944.rs b/rust-leetcode/src/leetcode_944.rs new file mode 100644 index 00000000..c037a9dc --- /dev/null +++ b/rust-leetcode/src/leetcode_944.rs @@ -0,0 +1,23 @@ +use std::ops::Index; + +use crate::pre_structs::Solution; + +///删列造序 +impl Solution { + //删除降序的,剩下非降序的 + //12ms + pub fn min_deletion_size(a: Vec) -> i32 { + let mut ret = 0; + let row = a.len(); + let col = a[0].len(); + for j in 0..col { + for i in 0..row - 1 { + if a[i].index(j..=j) > a[i + 1].index(j..=j) { + ret += 1; + break; + } + } + } + ret + } +} diff --git a/rust-leetcode/src/leetcode_977.rs b/rust-leetcode/src/leetcode_977.rs new file mode 100644 index 00000000..85f94204 --- /dev/null +++ b/rust-leetcode/src/leetcode_977.rs @@ -0,0 +1,30 @@ +use crate::pre_structs::Solution; + +///有序数组的平方 +impl Solution { + //172ms,2.1MB + pub fn sorted_squares(a: Vec) -> Vec { + let mut a = a; + a[0] = a[0] * a[0]; + for i in 1..a.len() { + let mut tmp = a[i] * a[i]; + let mut j = i; + while j > 0 && a[j - 1] > tmp { + a[j] = a[j - 1]; + j -= 1 + } + a[j] = tmp; + } + a + } + + //12ms,2.2MB + pub fn sorted_squares2(a: Vec) -> Vec { + let mut ret = a; + for (i, n) in ret.iter_mut().enumerate() { + *n = *n * *n; + } + ret.sort(); + ret + } +} diff --git a/rust-leetcode/src/leetcode_999.rs b/rust-leetcode/src/leetcode_999.rs new file mode 100644 index 00000000..46b5bdc4 --- /dev/null +++ b/rust-leetcode/src/leetcode_999.rs @@ -0,0 +1,43 @@ +use crate::pre_structs::Solution; + +///可以被一步捕获的棋子数 +impl Solution { + pub fn num_rook_captures(board: Vec>) -> i32 { + fn burnot(board: &Vec>, x: i32, y: i32, direction: &Vec) -> bool { + let mut i = x; + let mut j = y; + let closures = move |i: i32, j: i32| -> bool { i >= 0 && i < 8 && j >= 0 && j < 8 }; + while closures(i, j) { + //路被堵死 + if board[i as usize][j as usize] == 'B' { + break; + } + //是敌军 + if board[i as usize][j as usize] == 'p' { + return true; + } + i = i + direction[0]; + j = j + direction[1]; + } + return false; + } + + //定义方向数组,可以认为是四个方向向量,在棋盘问题上是常见的做法 + let directions = vec![vec![-1, 0], vec![1, 0], vec![0, 1], vec![0, -1]]; + for x in 0..8 { + for y in 0..8 { + if board[x][y] == 'R' { + let mut res = 0; + for direction in directions.iter() { + if burnot(&board, x as i32, y as i32, direction) { + res += 1; + } + } + return res; + } + } + } + + return 0; + } +} diff --git a/rust-leetcode/src/main.rs b/rust-leetcode/src/main.rs index d70fa63a..65495790 100644 --- a/rust-leetcode/src/main.rs +++ b/rust-leetcode/src/main.rs @@ -1,6 +1,71 @@ -use solution::*; +use old_solutions::*; -pub mod solution; +pub mod interview_01_01; +pub mod interview_02_02; +pub mod interview_03_04; +pub mod interview_04_02; +pub mod interview_05; +pub mod interview_06; +pub mod interview_09; +pub mod interview_16_07; +pub mod interview_17; +pub mod interview_22; +pub mod interview_24; +pub mod interview_25; +pub mod interview_27; +pub mod interview_32_2; +pub mod interview_54; +pub mod interview_55_1; +pub mod interview_58_2; +pub mod leetcode_1021; +pub mod leetcode_1051; +pub mod leetcode_108; +pub mod leetcode_1160; +pub mod leetcode_1207; +pub mod leetcode_1221; +pub mod leetcode_1252; +pub mod leetcode_1281; +pub mod leetcode_13; +pub mod leetcode_1304; +pub mod leetcode_1313; +pub mod leetcode_1323; +pub mod leetcode_1342; +pub mod leetcode_1351; +pub mod leetcode_1365; +pub mod leetcode_1370; +pub mod leetcode_1374; +pub mod leetcode_1380; +pub mod leetcode_1385; +pub mod leetcode_14; +pub mod leetcode_1403; +pub mod leetcode_1413; +pub mod leetcode_20; +pub mod leetcode_292; +pub mod leetcode_35; +pub mod leetcode_38; +pub mod leetcode_461; +pub mod leetcode_500; +pub mod leetcode_557; +pub mod leetcode_561; +pub mod leetcode_58; +pub mod leetcode_617; +pub mod leetcode_665; +pub mod leetcode_709; +pub mod leetcode_728; +pub mod leetcode_804; +pub mod leetcode_832; +pub mod leetcode_859; +pub mod leetcode_876; +pub mod leetcode_9; +pub mod leetcode_905; +pub mod leetcode_933; +pub mod leetcode_938; +pub mod leetcode_942; +pub mod leetcode_944; +pub mod leetcode_977; +pub mod leetcode_999; +pub mod old_solutions; +pub mod pre_structs; fn main() { println!("Hello, world!"); diff --git a/rust-leetcode/src/Solution.rs b/rust-leetcode/src/old_solutions.rs similarity index 85% rename from rust-leetcode/src/Solution.rs rename to rust-leetcode/src/old_solutions.rs index 732f3b08..5131a8d7 100644 --- a/rust-leetcode/src/Solution.rs +++ b/rust-leetcode/src/old_solutions.rs @@ -9,14 +9,14 @@ use std::str::Chars; use pre_structs::*; ///Leetcode 超简单的算法题目,主要为了熟悉rust语法 -///rust所必须的数据结构,Solution.rs源码中的行号对应README.md链接的#L参数,新增代码只能追加到最后 +///rust所必须的数据结构 +///old_solutions 是第一版,基本都带有测试(后续每个题都使用独立文件,测试暂无) mod pre_structs { use std::cell::RefCell; use std::rc::Rc; pub(crate) struct Solution; - //二叉树 #[derive(Debug, PartialEq, Eq)] pub struct TreeNode { @@ -40,24 +40,21 @@ mod pre_structs { #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32, - pub next: Option>,//堆上 + pub next: Option>, //堆上 } impl ListNode { #[inline] fn new(val: i32) -> Self { - ListNode { - next: None, - val, - } + ListNode { next: None, val } } } } ///二叉树的镜像 fn interview_27() { - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; impl Solution { pub fn mirror_tree(root: Option>>) -> Option>> { fn mirror(root: &mut Option>>) { @@ -79,15 +76,42 @@ fn interview_27() { } } - - let e1 = Some(Rc::new(RefCell::new(TreeNode { val: 1, left: None, right: None }))); - let e2 = Some(Rc::new(RefCell::new(TreeNode { val: 3, left: None, right: None }))); - let e3 = Some(Rc::new(RefCell::new(TreeNode { val: 6, left: None, right: None }))); - let e4 = Some(Rc::new(RefCell::new(TreeNode { val: 9, left: None, right: None }))); - let e5 = Some(Rc::new(RefCell::new(TreeNode { val: 2, left: e1, right: e2 }))); - let e6 = Some(Rc::new(RefCell::new(TreeNode { val: 7, left: e3, right: e4 }))); - let e7 = Some(Rc::new(RefCell::new(TreeNode { val: 4, left: e5, right: e6 }))); -// println!("{:?}", Solution::mirror_tree(e7)); + let e1 = Some(Rc::new(RefCell::new(TreeNode { + val: 1, + left: None, + right: None, + }))); + let e2 = Some(Rc::new(RefCell::new(TreeNode { + val: 3, + left: None, + right: None, + }))); + let e3 = Some(Rc::new(RefCell::new(TreeNode { + val: 6, + left: None, + right: None, + }))); + let e4 = Some(Rc::new(RefCell::new(TreeNode { + val: 9, + left: None, + right: None, + }))); + let e5 = Some(Rc::new(RefCell::new(TreeNode { + val: 2, + left: e1, + right: e2, + }))); + let e6 = Some(Rc::new(RefCell::new(TreeNode { + val: 7, + left: e3, + right: e4, + }))); + let e7 = Some(Rc::new(RefCell::new(TreeNode { + val: 4, + left: e5, + right: e6, + }))); + // println!("{:?}", Solution::mirror_tree(e7)); println!("{:?}", Solution::mirror_tree(e7)) } @@ -115,7 +139,7 @@ fn interview_02_02() { //倒数第k个,位置就是len-k。即快指针先走k步,然后2个指针同时走,快指针到达尾时,慢指针的位置就是第len-k个元素。此时快指针刚好走完一圈 pub fn kth_to_last2(head: Option>, k: i32) -> i32 { let mut i = k; - let mut fast = head.as_ref();//clone也可以,但没有必要,不能copy,没有实现Copy + let mut fast = head.as_ref(); //clone也可以,但没有必要,不能copy,没有实现Copy let mut slow = head.as_ref(); while i > 0 { if let Some(node) = fast.borrow() { @@ -199,7 +223,12 @@ fn leetcode_1351() { } } - let nums = vec![vec![4, 3, 2, -1], vec![3, 2, 1, -1], vec![1, 1, -1, -2], vec![-1, -1, -2, -3]]; + let nums = vec![ + vec![4, 3, 2, -1], + vec![3, 2, 1, -1], + vec![1, 1, -1, -2], + vec![-1, -1, -2, -3], + ]; println!("{}", Solution::count_negatives(nums)); } @@ -326,7 +355,7 @@ fn leetcode_1342() { n -= 1; } i += 1; - }; + } i } } @@ -363,7 +392,7 @@ fn leetcode_1313() { ///打印从1到最大的n位数 fn interview_17() { println!("interview_17"); - let num = ['9'; 10];//10个字符串9,这里10只能是一个常量,无法直接用于本题 + let num = ['9'; 10]; //10个字符串9,这里10只能是一个常量,无法直接用于本题 let mut max_num = String::new(); for i in num.iter() { max_num.push(*i) @@ -461,14 +490,13 @@ fn leetcode_1221() { } //函数式 pub fn balanced_string_split2(s: String) -> i32 { - s.chars().scan(0, |acc, e| { - *acc = if let 'R' = e { - (*acc + 1) - } else { - (*acc - 1) - }; - Some(*acc) - }).filter(|&e| e == 0).count() as i32 + s.chars() + .scan(0, |acc, e| { + *acc = if let 'R' = e { (*acc + 1) } else { (*acc - 1) }; + Some(*acc) + }) + .filter(|&e| e == 0) + .count() as i32 } } let ret = Solution::balanced_string_split("RLRRLLRLRL".to_string()); @@ -488,7 +516,9 @@ fn interview_06() { if let Some(root) = node { ret.push(root.val); node = root.next.as_ref(); - } else { break; } + } else { + break; + } } ret.reverse(); ret @@ -504,8 +534,8 @@ fn interview_06() { ///二叉搜索树的范围和 fn leetcode_938() { println!("leetcode_938"); - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; impl Solution { pub fn range_sum_bst(root: Option>>, l: i32, r: i32) -> i32 { let mut ret = 0; @@ -554,7 +584,7 @@ fn leetcode_938() { } ///删除最外层的括号 -fn lettcode_1021() { +fn leetcode_1021() { println!("lettcode_1021"); impl Solution { pub fn remove_outer_parentheses(s: String) -> String { @@ -595,8 +625,6 @@ fn lettcode_1021() { } } - - let ret = Solution::remove_outer_parentheses("(()())(())".to_string()); println!("{}", ret) } @@ -627,7 +655,7 @@ fn interview_24() { let e4 = Some(Box::new(ListNode { val: 2, next: e3 })); let e5 = Some(Box::new(ListNode { val: 1, next: e4 })); let ret = Solution::reverse_list(e5); - println!("{:?}", ret.unwrap());// 5 4 3 2 1 + println!("{:?}", ret.unwrap()); // 5 4 3 2 1 } ///奇数值单元格的数目 @@ -676,11 +704,14 @@ fn leetcode_1323() { ///合并二叉树 fn leetcode_617() { println!("leetcode_617"); - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; impl Solution { ///author 李广胜 - pub fn merge_trees(t1: Option>>, t2: Option>>) -> Option>> { + pub fn merge_trees( + t1: Option>>, + t2: Option>>, + ) -> Option>> { if t1.is_none() { return t2; } @@ -695,14 +726,23 @@ fn leetcode_617() { //直接b2.val编译错误 Some(Rc::new(RefCell::new(TreeNode { val: (*b1.as_ptr()).val + (*b2.as_ptr()).val, - left: Solution::merge_trees((*b1.as_ptr()).left.clone(), (*b2.as_ptr()).left.clone()), - right: Solution::merge_trees((*b1.as_ptr()).right.clone(), (*b2.as_ptr()).right.clone()), + left: Solution::merge_trees( + (*b1.as_ptr()).left.clone(), + (*b2.as_ptr()).left.clone(), + ), + right: Solution::merge_trees( + (*b1.as_ptr()).right.clone(), + (*b2.as_ptr()).right.clone(), + ), }))) } } ///author 长条人 - pub fn merge_trees2(t1: Option>>, t2: Option>>) -> Option>> { + pub fn merge_trees2( + t1: Option>>, + t2: Option>>, + ) -> Option>> { fn merge(t1: &mut Option>>, t2: &Option>>) { if let Some(mut n1) = t1.as_ref() { if let Some(n2) = t2 { @@ -713,7 +753,8 @@ fn leetcode_617() { merge(&mut (*n1.as_ptr()).left, &(*n2.as_ptr()).left); merge(&mut (*n1.as_ptr()).right, &(*n2.as_ptr()).right); } - } else {} + } else { + } } else { *t1 = t2.clone(); } @@ -752,12 +793,16 @@ fn leetcode_709() { println!("leetcode_709"); impl Solution { pub fn to_lower_case(str: String) -> String { - str.chars().map(|c| { - //说明是大写,+32 - if c < 'a' && c >= 'A' { - (c as u8 + 32 as u8) as char - } else { c } - }).collect() + str.chars() + .map(|c| { + //说明是大写,+32 + if c < 'a' && c >= 'A' { + (c as u8 + 32 as u8) as char + } else { + c + } + }) + .collect() } } let ret = Solution::to_lower_case("al&phaBET".to_string()); @@ -811,7 +856,11 @@ fn lettcode_804() { println!("lettcode_804"); impl Solution { pub fn unique_morse_representations(words: Vec) -> i32 { - let m = vec![".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."]; + let m = vec![ + ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", + ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", + "-..-", "-.--", "--..", + ]; let mut ret = HashSet::new(); for w in words.iter() { let mut mw = String::new(); @@ -826,7 +875,12 @@ fn lettcode_804() { } } - let words = vec!["gin".to_owned(), "zen".to_owned(), "gig".to_owned(), "msg".to_owned()]; + let words = vec![ + "gin".to_owned(), + "zen".to_owned(), + "gig".to_owned(), + "msg".to_owned(), + ]; let ret = Solution::unique_morse_representations(words); println!("{}", ret) } @@ -836,16 +890,20 @@ fn leetcode_832() { println!("leetcode_832"); impl Solution { pub fn flip_and_invert_image(a: Vec>) -> Vec> { - let ret: Vec> = a.iter().map(|mut row| -> Vec { - let mut new_row: Vec = row.iter().map(|x| -> i32 { - let new_x = if let 0 = x { - 1 - } else { 0 }; - new_x - }).collect(); - new_row.reverse(); - new_row - }).collect(); + let ret: Vec> = a + .iter() + .map(|mut row| -> Vec { + let mut new_row: Vec = row + .iter() + .map(|x| -> i32 { + let new_x = if let 0 = x { 1 } else { 0 }; + new_x + }) + .collect(); + new_row.reverse(); + new_row + }) + .collect(); ret } } @@ -864,8 +922,14 @@ fn leetcode_832() { fn interview_25() { println!("interview_25"); impl Solution { - pub fn merge_two_lists(l1: Option>, l2: Option>) -> Option> { - let mut result_head: Option> = Some(Box::new(ListNode { val: -1, next: None })); + pub fn merge_two_lists( + l1: Option>, + l2: Option>, + ) -> Option> { + let mut result_head: Option> = Some(Box::new(ListNode { + val: -1, + next: None, + })); let mut cur = &mut result_head; let mut l1 = l1; let mut l2 = l2; @@ -1077,7 +1141,7 @@ fn interview_01_01() { pub fn is_unique(astr: String) -> bool { let cs = astr.chars(); //题目没有说明,但这样AC了,假定只有大小写字母 - let mut count = vec![0; ('z' as i32 as usize) + 1];//123 + let mut count = vec![0; ('z' as i32 as usize) + 1]; //123 for c in cs { count[(c as i32) as usize] += 1; } @@ -1121,11 +1185,11 @@ fn leetcode_1385() { let ret = arr1.iter().for_each(|&x| { let mut flag = false; arr2.iter().for_each(|&y| { - if !flag && (x - y).abs() > d {} else { + if !flag && (x - y).abs() > d { + } else { flag = true; } - } - ); + }); if !flag { c += 1; } @@ -1140,8 +1204,8 @@ fn leetcode_1385() { ///二叉搜索树的第k大节点 fn interview_54() { println!("interview_54"); - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; impl Solution { pub fn kth_largest(root: Option>>, k: i32) -> i32 { let mut ret = Vec::new(); @@ -1159,14 +1223,30 @@ fn interview_54() { } for e in ret.iter() { println!("{}", e); - }; + } ret[(ret.len() - k as usize)] } } - let e2 = Some(Rc::new(RefCell::new(TreeNode { val: 2, left: None, right: None }))); - let e1 = Some(Rc::new(RefCell::new(TreeNode { val: 1, left: None, right: e2 }))); - let e4 = Some(Rc::new(RefCell::new(TreeNode { val: 4, left: None, right: None }))); - let root = Some(Rc::new(RefCell::new(TreeNode { val: 3, left: e1, right: e4 }))); + let e2 = Some(Rc::new(RefCell::new(TreeNode { + val: 2, + left: None, + right: None, + }))); + let e1 = Some(Rc::new(RefCell::new(TreeNode { + val: 1, + left: None, + right: e2, + }))); + let e4 = Some(Rc::new(RefCell::new(TreeNode { + val: 4, + left: None, + right: None, + }))); + let root = Some(Rc::new(RefCell::new(TreeNode { + val: 3, + left: e1, + right: e4, + }))); println!("{:?}", Solution::kth_largest(root, 4)) } @@ -1201,7 +1281,11 @@ fn interview_09() { } } let e = self.stack2.pop_back(); - if e.is_none() { -1 } else { e.unwrap().unwrap() } + if e.is_none() { + -1 + } else { + e.unwrap().unwrap() + } } } @@ -1336,7 +1420,7 @@ fn leetcode_1380() { fn leetcode_933() { println!("leetcode_933"); struct RecentCounter { - queue: VecDeque + queue: VecDeque, } /** @@ -1345,7 +1429,9 @@ fn leetcode_933() { */ impl RecentCounter { fn new() -> Self { - RecentCounter { queue: VecDeque::new() } + RecentCounter { + queue: VecDeque::new(), + } } fn ping(&mut self, t: i32) -> i32 { @@ -1395,8 +1481,8 @@ fn leetcode_561() { ///将有序数组转换为二叉搜索树 fn leetcode_108() { println!("leetcode_108"); - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; impl Solution { //与最小高度树 interview_04_02 一样 pub fn sorted_array_to_bst2(nums: Vec) -> Option>> { @@ -1432,7 +1518,7 @@ fn leetcode_1374() { ret = vec!['a'; n as usize]; } let mut rs = String::new(); - ret.iter().for_each(|&c| { rs.push(c) }); + ret.iter().for_each(|&c| rs.push(c)); rs } } @@ -1471,10 +1557,13 @@ fn leetcode_557() { impl Solution { pub fn reverse_words(s: String) -> String { let arr: Vec<&str> = s.split(' ').collect(); - let ret: Vec = arr.iter().map(|word| -> String { - let c: String = (*word).chars().rev().collect(); - c - }).collect(); + let ret: Vec = arr + .iter() + .map(|word| -> String { + let c: String = (*word).chars().rev().collect(); + c + }) + .collect(); ret.join(" ").to_string() } } @@ -1527,8 +1616,16 @@ fn leetcode_999() { } } - let d = vec![vec!['.', '.', '.', '.', '.', '.', '.', '.'], vec!['.', '.', '.', 'p', '.', '.', '.', '.'], vec!['.', '.', '.', 'R', '.', '.', '.', 'p'], vec!['.', '.', '.', '.', '.', '.', '.', '.'], vec!['.', '.', '.', '.', '.', '.', '.', '.'], vec!['.', '.', '.', 'p', '.', '.', '.', '.'], - vec!['.', '.', '.', '.', '.', '.', '.', '.'], vec!['.', '.', '.', '.', '.', '.', '.', '.']]; + let d = vec![ + vec!['.', '.', '.', '.', '.', '.', '.', '.'], + vec!['.', '.', '.', 'p', '.', '.', '.', '.'], + vec!['.', '.', '.', 'R', '.', '.', '.', 'p'], + vec!['.', '.', '.', '.', '.', '.', '.', '.'], + vec!['.', '.', '.', '.', '.', '.', '.', '.'], + vec!['.', '.', '.', 'p', '.', '.', '.', '.'], + vec!['.', '.', '.', '.', '.', '.', '.', '.'], + vec!['.', '.', '.', '.', '.', '.', '.', '.'], + ]; let ret = Solution::num_rook_captures(d); println!("{}", ret) } @@ -1538,7 +1635,11 @@ fn leetcode_292() { println!("leetcode_292"); impl Solution { pub fn can_win_nim(n: i32) -> bool { - if n % 4 == 0 { false } else { true } + if n % 4 == 0 { + false + } else { + true + } } } } @@ -1559,7 +1660,12 @@ fn leetcode_1160() { word_count[c as usize] += 1; } let mut flg = true; - if word.chars().map(|tc| -> bool { char_count[tc as usize] < word_count[tc as usize] }).find(|&x| x == true).is_some() { + if word + .chars() + .map(|tc| -> bool { char_count[tc as usize] < word_count[tc as usize] }) + .find(|&x| x == true) + .is_some() + { flg = false; } if flg { @@ -1570,11 +1676,20 @@ fn leetcode_1160() { } } - let ret = Solution::count_characters(vec!["skwgxuuuumkfurejmqrbipvlavdrozjyxhagbwetabjwevfsegqfpllgafm".to_owned(), "ufvpzzgpswnk".to_owned(), - "tcouxmlrnfyoxvkeglchhryykmdvgvdxpookbtiyhuthoqsnqbowewpfgbcy".to_owned(), - "qwpttmxzazkkfqqtrnkaejifligdvgnyvtmppjbkeuqryxzqyegttvhzolpztvigxygzvsppurijaekb".to_owned(), - "vbtvbheurzbglzljczmziitkbmtoybiwhoyfrsxvfveaxchebjdzdnnispzwbrgrbcdaistps".to_owned()] - .iter().map(|c| c.to_string()).collect(), "avyteswqppomeojxoybotzriuvxolmllevluauwb".to_owned()); + let ret = Solution::count_characters( + vec![ + "skwgxuuuumkfurejmqrbipvlavdrozjyxhagbwetabjwevfsegqfpllgafm".to_owned(), + "ufvpzzgpswnk".to_owned(), + "tcouxmlrnfyoxvkeglchhryykmdvgvdxpookbtiyhuthoqsnqbowewpfgbcy".to_owned(), + "qwpttmxzazkkfqqtrnkaejifligdvgnyvtmppjbkeuqryxzqyegttvhzolpztvigxygzvsppurijaekb" + .to_owned(), + "vbtvbheurzbglzljczmziitkbmtoybiwhoyfrsxvfveaxchebjdzdnnispzwbrgrbcdaistps".to_owned(), + ] + .iter() + .map(|c| c.to_string()) + .collect(), + "avyteswqppomeojxoybotzriuvxolmllevluauwb".to_owned(), + ); println!("{}", ret); } @@ -1603,8 +1718,8 @@ fn leetcode_1413() { ///从上到下打印二叉树 II fn interview_32_2() { println!("interview_32_2"); - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; impl Solution { //leetcode 102 pub fn level_order(root: Option>>) -> Vec> { @@ -1643,13 +1758,33 @@ fn interview_32_2() { } } - let e7 = Some(Rc::new(RefCell::new(TreeNode { val: 7, left: None, right: None }))); - let e15 = Some(Rc::new(RefCell::new(TreeNode { val: 15, left: None, right: None }))); - let e20 = Some(Rc::new(RefCell::new(TreeNode { val: 20, left: e15, right: e7 }))); - let e9 = Some(Rc::new(RefCell::new(TreeNode { val: 9, left: None, right: None }))); - let e3 = Some(Rc::new(RefCell::new(TreeNode { val: 3, left: e9, right: e20 }))); -// let e2 = Some(Rc::new(RefCell::new(TreeNode { val: 2, left: None, right: None }))); -// let e1 = Some(Rc::new(RefCell::new(TreeNode { val: 1, left: e2, right: None }))); + let e7 = Some(Rc::new(RefCell::new(TreeNode { + val: 7, + left: None, + right: None, + }))); + let e15 = Some(Rc::new(RefCell::new(TreeNode { + val: 15, + left: None, + right: None, + }))); + let e20 = Some(Rc::new(RefCell::new(TreeNode { + val: 20, + left: e15, + right: e7, + }))); + let e9 = Some(Rc::new(RefCell::new(TreeNode { + val: 9, + left: None, + right: None, + }))); + let e3 = Some(Rc::new(RefCell::new(TreeNode { + val: 3, + left: e9, + right: e20, + }))); + // let e2 = Some(Rc::new(RefCell::new(TreeNode { val: 2, left: None, right: None }))); + // let e1 = Some(Rc::new(RefCell::new(TreeNode { val: 1, left: e2, right: None }))); let ret = Solution::level_order(e3); for v in ret.iter() { for c in v.iter() { @@ -1680,20 +1815,22 @@ fn leetcode_944() { ret } } - let ret = Solution::min_deletion_size(vec!["cba".to_owned(), "daf".to_owned(), "ghi".to_owned()]); + let ret = + Solution::min_deletion_size(vec!["cba".to_owned(), "daf".to_owned(), "ghi".to_owned()]); println!("{}", ret); } - ///回文数 -fn leetcoode_9() { +fn leetcode_9() { println!("leetcoode_9"); impl Solution { //1.双指针,2.找规律,3.字符串,4.栈 pub fn is_palindrome(x: i32) -> bool { //4ms let mut n = x; - if n < 0 || (n != 0 && n % 10 == 0) { return false; } else { + if n < 0 || (n != 0 && n % 10 == 0) { + return false; + } else { let mut tmp = 0; while n > 0 { tmp = tmp * 10 + (n % 10); @@ -1736,7 +1873,9 @@ fn leetcode_13() { let n = vec![1, 5, 10, 50, 100, 500, 1000]; let mut ret = 0; let right = s.len() - 1; - n.iter().enumerate().for_each(|(x, &y)| { maps.insert(chs[x], y); }); + n.iter().enumerate().for_each(|(x, &y)| { + maps.insert(chs[x], y); + }); for i in 0..right { //字不是顺序的,但是数字列表是顺序的 if maps[s.index(i..=i)] >= maps[s.index(i + 1..=i + 1)] { @@ -1769,11 +1908,13 @@ fn leetcode_13() { return 0; } - s.chars().zip(s.chars().skip(1)).for_each(|(first, second)| { - let a = roman_to_int_char(first).unwrap(); - let b = roman_to_int_char(second).unwrap(); - v += (if a < b { -1 * a } else { a }); - }); + s.chars() + .zip(s.chars().skip(1)) + .for_each(|(first, second)| { + let a = roman_to_int_char(first).unwrap(); + let b = roman_to_int_char(second).unwrap(); + v += (if a < b { -1 * a } else { a }); + }); v += roman_to_int_char(s.chars().last().unwrap()).unwrap(); v @@ -1781,7 +1922,15 @@ fn leetcode_13() { //闲杂织造 pub fn roman_to_int3(s: String) -> i32 { - let tr = vec![('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000)]; + let tr = vec![ + ('I', 1), + ('V', 5), + ('X', 10), + ('L', 50), + ('C', 100), + ('D', 500), + ('M', 1000), + ]; let mut hash: HashMap = tr.iter().cloned().collect(); let chars: Vec = s.chars().collect(); let mut ans = 0; @@ -1831,24 +1980,63 @@ fn leetcode_876() { println!("{:?}", ret) } - ///键盘行 fn leetcode_500() { println!("leetcode_500"); impl Solution { pub fn find_words(words: Vec) -> Vec { - let map: HashMap = vec![('Q', 0), ('W', 0), ('E', 0), ('R', 0), ('T', 0), ('Y', 0), ('U', 0), ('I', 0), ('O', 0), ('P', 0), - ('A', 1), ('S', 1), ('D', 1), ('F', 1), ('G', 1), ('H', 1), ('J', 1), ('K', 1), ('L', 1), - ('Z', 2), ('X', 2), ('C', 2), ('V', 2), ('B', 2), ('N', 2), ('M', 2)].iter().cloned().collect(); - words.iter().filter(|word| { - let chars: Vec = word.chars().collect(); - let index: HashSet = chars.iter().map(|c| -> i32 { map[&c.to_ascii_uppercase()] }).collect(); - index.len() == 1 - }).cloned().collect() - } - } - - let ret = Solution::find_words(vec!["Hello".to_string(), "Alaska".to_string(), "Dad".to_string(), "Peace".to_string()]); + let map: HashMap = vec![ + ('Q', 0), + ('W', 0), + ('E', 0), + ('R', 0), + ('T', 0), + ('Y', 0), + ('U', 0), + ('I', 0), + ('O', 0), + ('P', 0), + ('A', 1), + ('S', 1), + ('D', 1), + ('F', 1), + ('G', 1), + ('H', 1), + ('J', 1), + ('K', 1), + ('L', 1), + ('Z', 2), + ('X', 2), + ('C', 2), + ('V', 2), + ('B', 2), + ('N', 2), + ('M', 2), + ] + .iter() + .cloned() + .collect(); + words + .iter() + .filter(|word| { + let chars: Vec = word.chars().collect(); + let index: HashSet = chars + .iter() + .map(|c| -> i32 { map[&c.to_ascii_uppercase()] }) + .collect(); + index.len() == 1 + }) + .cloned() + .collect() + } + } + + let ret = Solution::find_words(vec![ + "Hello".to_string(), + "Alaska".to_string(), + "Dad".to_string(), + "Peace".to_string(), + ]); print_vec_string(ret); } @@ -1932,12 +2120,20 @@ fn leetcode_14() { } } - let ret = Solution::longest_common_prefix(vec!["flower".to_owned(), "flow".to_owned(), "flight".to_owned()]); + let ret = Solution::longest_common_prefix(vec![ + "flower".to_owned(), + "flow".to_owned(), + "flight".to_owned(), + ]); let ret2 = Solution::longest_common_prefix(vec![]); println!("{}", ret); println!("{}", ret2); - let ret = Solution::longest_common_prefix2(vec!["flower".to_owned(), "flow".to_owned(), "flight".to_owned()]); + let ret = Solution::longest_common_prefix2(vec![ + "flower".to_owned(), + "flow".to_owned(), + "flight".to_owned(), + ]); let ret2 = Solution::longest_common_prefix2(vec![]); println!("{}", ret); println!("{}", ret2); @@ -1964,7 +2160,10 @@ fn leetcode_20() { } let c_stack = stack.pop(); if let Some(cStack) = c_stack { - if c == ')' && cStack != '(' || c == ']' && cStack != '[' || c == '}' && cStack != '{' { + if c == ')' && cStack != '(' + || c == ']' && cStack != '[' + || c == '}' && cStack != '{' + { return false; } } @@ -1977,7 +2176,6 @@ fn leetcode_20() { println!("{}", ret); } - ///搜索插入位置 fn leetcode_35() { println!("leetcode_35"); @@ -1987,7 +2185,7 @@ fn leetcode_35() { //找到知己反回索引,没有找到则返回该元素插入后保持数组仍然有序的索引位置,主要用于有序的数组/向量 let ret = match nums.binary_search(&target) { Ok(found_index) => found_index, - Err(maybe_insert) => maybe_insert + Err(maybe_insert) => maybe_insert, }; ret as i32 } @@ -2017,7 +2215,11 @@ fn leetcode_1207() { pub fn unique_occurrences(arr: Vec) -> bool { let mut map = HashMap::new(); for num in arr.iter() { - let n = if map.contains_key(num) { map.get(num).unwrap() } else { &0 }; + let n = if map.contains_key(num) { + map.get(num).unwrap() + } else { + &0 + }; if map.contains_key(num) { map.insert(num, *n + 1); } else { @@ -2042,7 +2244,9 @@ fn leetcode_38() { //描述上一步的数,这个数是21即一个2一个1,故写作12-11 //描述上一步的数,这个数是1211即一个1一个2两个1,故写作11-12-21 pub fn count_and_say(n: i32) -> String { - if n == 1 { return "1".to_owned(); } + if n == 1 { + return "1".to_owned(); + } let pre_str = Solution::count_and_say(n - 1); let mut curr_str = String::new(); let mut pre_char = None; @@ -2109,7 +2313,8 @@ fn leetcode_665() { } else if nums[i - 1] > nums[i + 1] { //如果 i-1 和 i+1 是降序排列,此时增大 i+1 的值 nums[i + 1] = nums[i]; - } else {} + } else { + } //计算需要改动的次数 cnt += 1; if cnt > 1 { @@ -2143,7 +2348,7 @@ pub fn solutions() { leetcode_1221(); interview_06(); leetcode_938(); - lettcode_1021(); + leetcode_1021(); interview_24(); leetcode_1252(); leetcode_1323(); @@ -2178,7 +2383,7 @@ pub fn solutions() { leetcode_1413(); interview_32_2(); leetcode_944(); - leetcoode_9(); + leetcode_9(); leetcode_13(); leetcode_876(); leetcode_500(); @@ -2202,4 +2407,4 @@ fn print_vec_string(nums: Vec) { for e in nums.iter() { println!("{}", e); } -} \ No newline at end of file +} diff --git a/rust-leetcode/src/pre_structs.rs b/rust-leetcode/src/pre_structs.rs new file mode 100644 index 00000000..77a1957a --- /dev/null +++ b/rust-leetcode/src/pre_structs.rs @@ -0,0 +1,37 @@ +use std::cell::RefCell; +use std::rc::Rc; + +pub(crate) struct Solution; + +//二叉树 +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +//单链表 +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, //堆上 +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} diff --git a/rust-minigrep/src/lib.rs b/rust-minigrep/src/lib.rs index 5edec5f0..a47dfa92 100644 --- a/rust-minigrep/src/lib.rs +++ b/rust-minigrep/src/lib.rs @@ -24,20 +24,24 @@ impl Config { None => return Err("Didn't get a file name"), }; let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); - Ok(Config { query, filename, case_sensitive }) + Ok(Config { + query, + filename, + case_sensitive, + }) } -// pub fn new(args: &[String]) -> Result { -// //构造时限制参数 -// if args.len() < 3 { -// //panic!("not enough arguments"); -// return Err("not enough arguments"); -// } -// let query = args[1].clone(); -// let filename = args[2].clone(); -// //获取环境变量 -// let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); -// Ok(Config { query, filename, case_sensitive }) -// } + // pub fn new(args: &[String]) -> Result { + // //构造时限制参数 + // if args.len() < 3 { + // //panic!("not enough arguments"); + // return Err("not enough arguments"); + // } + // let query = args[1].clone(); + // let filename = args[2].clone(); + // //获取环境变量 + // let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + // Ok(Config { query, filename, case_sensitive }) + // } } ///现在,只知道这Box意味着函数将返回实现该Error特征的类型,但是我们不必指定返回值将是哪种特定类型。 @@ -65,7 +69,6 @@ pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { results } - ///忽略大小写的查询 pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { let query = query.to_lowercase(); @@ -81,5 +84,8 @@ pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a st ///使用迭代器和闭包的简洁查询函数 pub fn search2<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - contents.lines().filter(|line| line.contains(query)).collect() -} \ No newline at end of file + contents + .lines() + .filter(|line| line.contains(query)) + .collect() +} diff --git a/rust-minigrep/src/main.rs b/rust-minigrep/src/main.rs index 77514442..42b589b6 100644 --- a/rust-minigrep/src/main.rs +++ b/rust-minigrep/src/main.rs @@ -3,7 +3,7 @@ use std::error::Error; use std::fs; use std::process; -use rust_minigrep::{Config, run}; +use rust_minigrep::{run, Config}; ///主函数,必须命令行执行(需要传参数) ///cargo run to poem.txt > output.txt 将结果输出到文件中 @@ -26,10 +26,14 @@ fn main() { ///相比下面而言更好的选择是将config作为一个结构体 fn parse_config2(args: &[String]) -> Config { - let query = args[1].clone();//clone的运行时成本在这里不考虑 + let query = args[1].clone(); //clone的运行时成本在这里不考虑 let filename = args[2].clone(); let case_sensitive = false; - Config { query, filename, case_sensitive } + Config { + query, + filename, + case_sensitive, + } } fn parse_config(args: &[String]) -> (&str, &str) { @@ -53,10 +57,7 @@ Rust: safe, fast, productive. Pick three."; - assert_eq!( - vec!["safe, fast, productive."], - search(query, contents) - ); + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); } #[test] diff --git a/rust-oop/src/lib.rs b/rust-oop/src/lib.rs index 06ededd3..b1a635ea 100644 --- a/rust-oop/src/lib.rs +++ b/rust-oop/src/lib.rs @@ -32,7 +32,6 @@ pub mod gui { } } - //Button,Image,和SelectBox,将从继承Component并且因此继承draw方法。 //他们每个人都可以重写该draw方法来定义其自定义行为 //rust没有继承,需要使用其他方法实现这一功能 @@ -43,7 +42,7 @@ pub mod gui { //使用Screen将限制为一个Screen实例,该实例具有一个全部为Button类型或全部TextField类型的组件的列表。 //如果您只拥有同类集合,则最好使用泛型和特质范围,因为定义会在编译时被单一化以使用具体类型。 pub struct Screen { - pub components: Vec>,//Box 实现了Draw特质的任何类型组件 + pub components: Vec>, //Box 实现了Draw特质的任何类型组件 } impl Screen { @@ -67,7 +66,6 @@ pub mod gui { } } - pub struct SelectBox { pub width: u32, pub height: u32, @@ -84,4 +82,3 @@ pub mod gui { //安全的特质对象 //返回类型不是Self。 //没有通用类型参数。 - diff --git a/rust-oop/src/main.rs b/rust-oop/src/main.rs index 4cd2a7c8..91b0203b 100644 --- a/rust-oop/src/main.rs +++ b/rust-oop/src/main.rs @@ -15,7 +15,7 @@ fn main() { options: vec![ String::from("Yes"), String::from("Maybe"), - String::from("No") + String::from("No"), ], }), Box::new(Button { @@ -28,7 +28,6 @@ fn main() { screen.run(); - blog(); blog_rust(); -} \ No newline at end of file +} diff --git a/rust-oop/src/oop_blog.rs b/rust-oop/src/oop_blog.rs index bcbf1220..8a739d13 100644 --- a/rust-oop/src/oop_blog.rs +++ b/rust-oop/src/oop_blog.rs @@ -108,4 +108,4 @@ pub mod blog_lib { &post.content } } -} \ No newline at end of file +} diff --git a/rust-oop/src/rust_blog.rs b/rust-oop/src/rust_blog.rs index 5347e573..a8d75a7c 100644 --- a/rust-oop/src/rust_blog.rs +++ b/rust-oop/src/rust_blog.rs @@ -53,4 +53,4 @@ pub mod blog_lib { } } } -} \ No newline at end of file +} -- GitLab