From 0faf19fd0263f423641c8ec9dffa7a36a9da6de2 Mon Sep 17 00:00:00 2001 From: finchxx <1470073710@qq.com> Date: Thu, 6 Feb 2025 11:01:55 +0800 Subject: [PATCH] finish --- exercises/algorithm/algorithm10.rs | 28 ++++++++++++- exercises/algorithm/algorithm5.rs | 21 ++++++++-- exercises/algorithm/algorithm6.rs | 23 ++++++++++- exercises/algorithm/algorithm7.rs | 38 +++++++++++++++-- exercises/algorithm/algorithm8.rs | 26 ++++++++++-- exercises/algorithm/algorithm9.rs | 66 ++++++++++++++++++++++++++---- 6 files changed, 180 insertions(+), 22 deletions(-) diff --git a/exercises/algorithm/algorithm10.rs b/exercises/algorithm/algorithm10.rs index a2ad731d0..53044b01a 100644 --- a/exercises/algorithm/algorithm10.rs +++ b/exercises/algorithm/algorithm10.rs @@ -2,7 +2,6 @@ graph This problem requires you to implement a basic graph functio */ -// I AM NOT DONE use std::collections::{HashMap, HashSet}; use std::fmt; @@ -30,6 +29,33 @@ impl Graph for UndirectedGraph { } fn add_edge(&mut self, edge: (&str, &str, i32)) { //TODO + if let (e1, e2, number) = edge { + self.adjacency_table + .entry(String::from(e1)) + .and_modify(|relations| { + // relations.iter_mut() + // .filter(|(s, _)| s == e2) + // .for_each(|(_, num)| *num += number); + if let Some(index) = relations.iter().position(|(s, _)| s == e2) { + relations[index].1 += number; + } else { + relations.push((e2.to_string(), number)); + } + }) + .or_insert_with(|| vec![(String::from(e2), number)]); // 如果 `e1` 不存在,插入新元素 + + self.adjacency_table + .entry(String::from(e2)) + .and_modify(|relations| { + if let Some(index) = relations.iter().position(|(s, _)| s == e1) { + relations[index].1 += number; + } else { + relations.push((e1.to_string(), number)); + } + }) + .or_insert_with(|| vec![(String::from(e1), number)]); + } + } } pub trait Graph { diff --git a/exercises/algorithm/algorithm5.rs b/exercises/algorithm/algorithm5.rs index 8f206d1a9..742be414d 100644 --- a/exercises/algorithm/algorithm5.rs +++ b/exercises/algorithm/algorithm5.rs @@ -3,7 +3,6 @@ This problem requires you to implement a basic BFS algorithm */ -//I AM NOT DONE use std::collections::VecDeque; // Define a graph @@ -27,10 +26,24 @@ impl Graph { // Perform a breadth-first search on the graph, return the order of visited nodes fn bfs_with_return(&self, start: usize) -> Vec { - - //TODO - let mut visit_order = vec![]; + let mut visited = vec![false; self.adj.len()]; + let mut queue = VecDeque::new(); + + visited[start] = true; + queue.push_back(start); + + while let Some(node) = queue.pop_front() { + visit_order.push(node); + + for &neighbor in &self.adj[node] { + if !visited[neighbor] { + visited[neighbor] = true; + queue.push_back(neighbor); + } + } + } + visit_order } } diff --git a/exercises/algorithm/algorithm6.rs b/exercises/algorithm/algorithm6.rs index 813146f7c..ff1a48961 100644 --- a/exercises/algorithm/algorithm6.rs +++ b/exercises/algorithm/algorithm6.rs @@ -3,7 +3,6 @@ This problem requires you to implement a basic DFS traversal */ -// I AM NOT DONE use std::collections::HashSet; struct Graph { @@ -23,7 +22,16 @@ impl Graph { } fn dfs_util(&self, v: usize, visited: &mut HashSet, visit_order: &mut Vec) { - //TODO + if self.adj[v].len() <= 0 || visited.contains(&v){ + return; + } + visited.insert(v); + visit_order.push(v); + for &out_edge in &self.adj[v] { + self.dfs_util(out_edge, visited, visit_order); + // visited.remove(&v); + // visit_order.pop(); + } } // Perform a depth-first search on the graph, return the order of visited nodes @@ -39,6 +47,17 @@ impl Graph { mod tests { use super::*; + + #[test] + fn test_dfs_simple_0() { + let mut graph = Graph::new(2); + graph.add_edge(0, 1); + + let visit_order = graph.dfs(0); + assert_eq!(visit_order, vec![0, 1]); + } + + #[test] fn test_dfs_simple() { let mut graph = Graph::new(3); diff --git a/exercises/algorithm/algorithm7.rs b/exercises/algorithm/algorithm7.rs index e0c3a5ab2..8ea83ef53 100644 --- a/exercises/algorithm/algorithm7.rs +++ b/exercises/algorithm/algorithm7.rs @@ -3,7 +3,6 @@ This question requires you to use a stack to achieve a bracket match */ -// I AM NOT DONE #[derive(Debug)] struct Stack { size: usize, @@ -32,7 +31,14 @@ impl Stack { } fn pop(&mut self) -> Option { // TODO - None + if self.size <= 0 { + return None; + } + + self.size -= 1; + return self.data.pop(); + + } fn peek(&self) -> Option<&T> { if 0 == self.size { @@ -102,7 +108,33 @@ impl<'a, T> Iterator for IterMut<'a, T> { fn bracket_match(bracket: &str) -> bool { //TODO - true + let mut operator_stack = Stack::::new(); + for c in bracket.chars() { + match c { + c if c == '{' || c == '[' || c == '(' => { + operator_stack.push(c); + } + + c if c == '}' || c == ']' || c == ')' => { + if let Some(out) = operator_stack.pop() { + if (c == '}' && out != '{') || (c == ']' && out != '[') || (c == ')' && out != '(') { + return false; + } + } else { + return false; + } + + + + } + _ => {} + } + } + if operator_stack.len() > 0 { + false + } else { + true + } } #[cfg(test)] diff --git a/exercises/algorithm/algorithm8.rs b/exercises/algorithm/algorithm8.rs index d1d183b84..5a786203e 100644 --- a/exercises/algorithm/algorithm8.rs +++ b/exercises/algorithm/algorithm8.rs @@ -2,7 +2,6 @@ queue This question requires you to use queues to implement the functionality of the stac */ -// I AM NOT DONE #[derive(Debug)] pub struct Queue { @@ -68,14 +67,33 @@ impl myStack { } pub fn push(&mut self, elem: T) { //TODO + self.q1.enqueue(elem); } pub fn pop(&mut self) -> Result { - //TODO - Err("Stack is empty") + if self.q1.is_empty() && self.q2.is_empty() { + return Err("Stack is empty"); + } + + // 确定哪个队列作为源(source) + let (source, dest) = if !self.q1.is_empty() { + (&mut self.q1, &mut self.q2) + } else { + (&mut self.q2, &mut self.q1) + }; + + // 转移元素直到源队列只剩一个 + while source.size() > 1 { + let elem = source.dequeue().map_err(|_| "Dequeue failed")?; + dest.enqueue(elem); + } + + // 弹出最后一个元素 + source.dequeue().map_err(|_| "Dequeue failed") } pub fn is_empty(&self) -> bool { //TODO - true + self.q1.size() == 0 && self.q2.size() == 0 + // true } } diff --git a/exercises/algorithm/algorithm9.rs b/exercises/algorithm/algorithm9.rs index 6c8021a4d..a163d5c3d 100644 --- a/exercises/algorithm/algorithm9.rs +++ b/exercises/algorithm/algorithm9.rs @@ -2,7 +2,6 @@ heap This question requires you to implement a binary heap function */ -// I AM NOT DONE use std::cmp::Ord; use std::default::Default; @@ -36,8 +35,28 @@ where self.len() == 0 } - pub fn add(&mut self, value: T) { + pub fn add(&mut self, value: T) where T: PartialOrd { //TODO + if self.count <= 0 { + self.items[0] = value; + self.count += 1; + return; + } + self.items.push(value); + self.count += 1; + let mut current_index = self.items.len() - 1; + while current_index > 0 { + let pindex = self.parent_idx(current_index); + let pnode = &self.items[pindex]; + let current_node = &self.items[current_index]; + if !(self.comparator)(pnode, current_node) { + self.items.swap(pindex, current_index); + current_index = pindex; + } else { + break; + } + + } } fn parent_idx(&self, idx: usize) -> usize { @@ -45,7 +64,7 @@ where } fn children_present(&self, idx: usize) -> bool { - self.left_child_idx(idx) <= self.count + self.left_child_idx(idx) < self.count } fn left_child_idx(&self, idx: usize) -> usize { @@ -57,8 +76,19 @@ where } fn smallest_child_idx(&self, idx: usize) -> usize { - //TODO - 0 + + let left = self.left_child_idx(idx); + let right = self.right_child_idx(idx); + + if right < self.count { + if (self.comparator)(&self.items[right], &self.items[left]) { + right + } else { + left + } + } else { + left + } } } @@ -79,13 +109,33 @@ where impl Iterator for Heap where - T: Default, + T: Default + Ord, { type Item = T; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option{ //TODO - None + if self.count == 0 { + return None; + } + let last_idx = self.count - 1; + self.items.swap(0, last_idx); + let result = self.items.pop().unwrap(); + self.count -= 1; + + let mut current_index = 0; + while self.children_present(current_index) { + let child_idx = self.smallest_child_idx(current_index); + if (self.comparator)(&self.items[child_idx], &self.items[current_index]) { + self.items.swap(current_index, child_idx); + current_index = child_idx; + } else { + break; + } + + } + + return Some(result); } }