Skip to content

Commit b9bee36

Browse files
Merge pull request #354 from caitlingao/feat-rust-08-stack
feat(geektime_algo): add 08_stack
2 parents f7f83ce + afa1910 commit b9bee36

File tree

3 files changed

+194
-0
lines changed

3 files changed

+194
-0
lines changed

rust/08_stack/simple_browser.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
mod stack_based_on_linked_list;
2+
3+
use stack_based_on_linked_list::{LinkedListStack};
4+
5+
#[derive(Hash, Eq, PartialEq, Debug, Default, Clone)]
6+
struct Browser {
7+
forward_stack: LinkedListStack,
8+
back_stack: LinkedListStack,
9+
current_page: String,
10+
}
11+
12+
impl Browser {
13+
fn new() -> Self {
14+
Default::default()
15+
}
16+
17+
fn open(&mut self, url: &String) {
18+
if !self.current_page.is_empty() {
19+
self.back_stack.push(self.current_page.clone());
20+
self.forward_stack.clear();
21+
}
22+
self.show_url(&url, "Open".to_string());
23+
}
24+
25+
fn go_back(&mut self) -> String {
26+
if self.can_go_back() {
27+
self.forward_stack.push(self.current_page.clone());
28+
let back_url = self.back_stack.pop();
29+
self.show_url(&back_url, "Back".to_string());
30+
return back_url;
31+
}
32+
33+
println!("Can not go back, there is no page behind.");
34+
"-1".to_string()
35+
}
36+
37+
fn go_forward(&mut self) -> String {
38+
if self.can_go_forward() {
39+
self.back_stack.push(self.current_page.clone());
40+
let forward_url = self.forward_stack.pop();
41+
self.show_url(&forward_url, "Forward".to_string());
42+
return forward_url;
43+
}
44+
45+
println!("Can not go forward, there is no page behind.");
46+
"-1".to_string()
47+
}
48+
49+
fn can_go_back(&self) -> bool {
50+
!self.back_stack.is_empty()
51+
}
52+
53+
fn can_go_forward(&self) -> bool {
54+
!self.forward_stack.is_empty()
55+
}
56+
57+
fn show_url(&mut self, url: &String, prefix: String) {
58+
self.current_page = url.to_string();
59+
println!("{:?} page == {:?}", prefix, url);
60+
}
61+
62+
fn check_current_page(&self) {
63+
println!("current page == {:?}", self.current_page);
64+
}
65+
}
66+
fn main() {
67+
let mut browser = Browser::new();
68+
browser.open(&"http://www.baidu.com".to_string());
69+
browser.open(&"http://news.baidu.com/".to_string());
70+
browser.open(&"http://news.baidu.com/ent".to_string());
71+
browser.go_back();
72+
browser.go_back();
73+
browser.go_forward();
74+
browser.open(&"http://www.qq.com".to_string());
75+
browser.go_forward();
76+
browser.go_back();
77+
browser.go_forward();
78+
browser.go_back();
79+
browser.go_back();
80+
browser.go_back();
81+
browser.go_back();
82+
browser.check_current_page();
83+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#[derive(Debug)]
2+
struct ArrayStack {
3+
data: Vec<i32>,
4+
top: i32,
5+
}
6+
7+
impl ArrayStack {
8+
fn new() -> Self {
9+
ArrayStack { data: Vec::with_capacity(32), top: -1 }
10+
}
11+
12+
fn push(&mut self, x: i32) {
13+
self.top += 1;
14+
if self.top == self.data.capacity() as i32 {
15+
let tmp_arr = self.data.clone();
16+
self.data = Vec::with_capacity(self.data.capacity() * 2);
17+
for d in tmp_arr.into_iter() {
18+
self.data.push(d);
19+
}
20+
}
21+
self.data.push(x);
22+
}
23+
24+
fn pop(&mut self) {
25+
if self.is_empty() { return; }
26+
self.top -= 1;
27+
self.data.pop();
28+
}
29+
30+
fn top(&self) -> i32 {
31+
if self.is_empty() { return -1; }
32+
*self.data.last().unwrap()
33+
}
34+
35+
fn is_empty(&self) -> bool {
36+
if self.top < 0 { true } else { false }
37+
}
38+
}
39+
40+
fn main() {
41+
let mut stack = ArrayStack::new();
42+
stack.push(-2);
43+
stack.push(0);
44+
stack.push(-3);
45+
stack.pop();
46+
println!("{:?}", stack.top());
47+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#[derive(Hash, Eq, PartialEq, Debug, Default, Clone)]
2+
pub struct ListNode {
3+
val: String,
4+
next: Option<Box<ListNode>>,
5+
}
6+
7+
#[derive(Hash, Eq, PartialEq, Debug, Default, Clone)]
8+
pub struct LinkedListStack {
9+
node: Option<Box<ListNode>>,
10+
}
11+
12+
impl ListNode {
13+
fn new(val: String) -> Self {
14+
ListNode { val: val, next: None }
15+
}
16+
}
17+
18+
impl LinkedListStack {
19+
pub fn new() -> Self {
20+
Default::default()
21+
}
22+
23+
pub fn push(&mut self, x: String) {
24+
let mut n = ListNode::new(x);
25+
n.next = self.node.clone();
26+
self.node = Some(Box::new(n));
27+
}
28+
29+
pub fn pop(&mut self) -> String {
30+
if self.is_empty() { return "-1".to_string(); }
31+
32+
let val = self.node.as_ref().unwrap().val.clone();
33+
self.node = self.node.as_mut().unwrap().next.take();
34+
val.to_string()
35+
}
36+
37+
pub fn print_all(&mut self) {
38+
let mut list = String::from("");
39+
40+
while let Some(n) = self.node.as_mut() {
41+
list.push_str(&(n.val).to_string());
42+
list.push_str("-->");
43+
self.node = n.next.take();
44+
}
45+
println!("{:?}", list);
46+
}
47+
48+
pub fn clear(&mut self) {
49+
self.node = None;
50+
}
51+
52+
pub fn is_empty(&self) -> bool {
53+
if self.node.is_none() { true } else { false }
54+
}
55+
}
56+
//
57+
// fn main() {
58+
// let mut stack = LinkedListStack::new();
59+
// stack.push("https://www.baidu.com".to_string());
60+
// stack.push("https://www.google.com".to_string());
61+
// stack.pop();
62+
// stack.push("https://twitter.com".to_string());
63+
// stack.print_all();
64+
// }

0 commit comments

Comments
 (0)