2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,23 +1,39 @@
|
|||
{{data structure}}[[Category:Classic CS problems and programs]]
|
||||
A '''stack''' is a container of elements with last in, first out access policy.
|
||||
Sometimes it also called '''LIFO'''. The stack is accessed through its '''top'''.
|
||||
|
||||
A '''stack''' is a container of elements with <big><u>l</u>ast <u>i</u>n, <u>f</u>irst <u>o</u>ut</big> access policy. Sometimes it also called '''LIFO'''.
|
||||
|
||||
The stack is accessed through its '''top'''.
|
||||
|
||||
The basic stack operations are:
|
||||
|
||||
* ''push'' stores a new element onto the stack top;
|
||||
* ''pop'' returns the last pushed stack element, while removing it from the stack;
|
||||
* ''empty'' tests if the stack contains no elements.
|
||||
* ''push'' stores a new element onto the stack top;
|
||||
* ''pop'' returns the last pushed stack element, while removing it from the stack;
|
||||
* ''empty'' tests if the stack contains no elements.
|
||||
|
||||
<br>
|
||||
Sometimes the last pushed stack element is made accessible for immutable access (for read) or mutable access (for write):
|
||||
|
||||
* ''top'' (sometimes called ''peek'' to keep with the ''p'' theme) returns the topmost element without modifying the stack.
|
||||
* ''top'' (sometimes called ''peek'' to keep with the ''p'' theme) returns the topmost element without modifying the stack.
|
||||
|
||||
<br>
|
||||
Stacks allow a very simple hardware implementation.
|
||||
They are common in almost all processors. In programming stacks are also very popular for their way ('''LIFO''') of resource management, usually memory.
|
||||
|
||||
They are common in almost all processors.
|
||||
|
||||
In programming, stacks are also very popular for their way ('''LIFO''') of resource management, usually memory.
|
||||
|
||||
Nested scopes of language objects are naturally implemented by a stack (sometimes by multiple stacks).
|
||||
This is a classical way to implement local variables of a reentrant or recursive subprogram. Stacks are also used to describe a formal computational framework.
|
||||
|
||||
This is a classical way to implement local variables of a re-entrant or recursive subprogram. Stacks are also used to describe a formal computational framework.
|
||||
|
||||
See [[wp:Stack_automaton|stack machine]].
|
||||
|
||||
Many algorithms in pattern matching, compiler construction (e.g. [[wp:Recursive_descent|recursive descent parsers]]), and machine learning (e.g. based on [[wp:Tree_traversal|tree traversal]]) have a natural representation in terms of stacks.
|
||||
|
||||
|
||||
;Task:
|
||||
Create a stack supporting the basic operations: push, pop, empty.
|
||||
|
||||
|
||||
{{Template:See also lists}}
|
||||
<br><br>
|
||||
|
|
|
|||
9
Task/Stack/Elena/stack.elena
Normal file
9
Task/Stack/Elena/stack.elena
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#var stack := system'collections'Stack new.
|
||||
|
||||
stack push:2.
|
||||
|
||||
#var isEmpty := stack length == 0.
|
||||
|
||||
#var item := stack peek. // Peek without Popping.
|
||||
|
||||
item := stack pop.
|
||||
25
Task/Stack/K/stack.k
Normal file
25
Task/Stack/K/stack.k
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
stack:()
|
||||
push:{stack::x,stack}
|
||||
pop:{r:*stack;stack::1_ stack;r}
|
||||
empty:{0=#stack}
|
||||
|
||||
/example:
|
||||
stack:()
|
||||
push 3
|
||||
stack
|
||||
,3
|
||||
push 5
|
||||
stack
|
||||
5 3
|
||||
pop[]
|
||||
5
|
||||
stack
|
||||
,3
|
||||
empty[]
|
||||
0
|
||||
pop[]
|
||||
3
|
||||
stack
|
||||
!0
|
||||
empty[]
|
||||
1
|
||||
66
Task/Stack/Oberon-2/stack-1.oberon-2
Normal file
66
Task/Stack/Oberon-2/stack-1.oberon-2
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
MODULE Stacks;
|
||||
IMPORT
|
||||
Object,
|
||||
Object:Boxed,
|
||||
Out := NPCT:Console;
|
||||
|
||||
TYPE
|
||||
Pool(E: Object.Object) = POINTER TO ARRAY OF E;
|
||||
Stack*(E: Object.Object) = POINTER TO StackDesc(E);
|
||||
StackDesc*(E: Object.Object) = RECORD
|
||||
pool: Pool(E);
|
||||
cap-,top: LONGINT;
|
||||
END;
|
||||
|
||||
PROCEDURE (s: Stack(E)) INIT*(cap: LONGINT);
|
||||
BEGIN
|
||||
NEW(s.pool,cap);s.cap := cap;s.top := -1
|
||||
END INIT;
|
||||
|
||||
PROCEDURE (s: Stack(E)) Top*(): E;
|
||||
BEGIN
|
||||
RETURN s.pool[s.top]
|
||||
END Top;
|
||||
|
||||
PROCEDURE (s: Stack(E)) Push*(e: E);
|
||||
BEGIN
|
||||
INC(s.top);
|
||||
ASSERT(s.top < s.cap);
|
||||
s.pool[s.top] := e;
|
||||
END Push;
|
||||
|
||||
PROCEDURE (s: Stack(E)) Pop*(): E;
|
||||
VAR
|
||||
resp: E;
|
||||
BEGIN
|
||||
ASSERT(s.top >= 0);
|
||||
resp := s.pool[s.top];DEC(s.top);
|
||||
RETURN resp
|
||||
END Pop;
|
||||
|
||||
PROCEDURE (s: Stack(E)) IsEmpty(): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN s.top < 0
|
||||
END IsEmpty;
|
||||
|
||||
PROCEDURE (s: Stack(E)) Size*(): LONGINT;
|
||||
BEGIN
|
||||
RETURN s.top + 1
|
||||
END Size;
|
||||
|
||||
PROCEDURE Test;
|
||||
VAR
|
||||
s: Stack(Boxed.LongInt);
|
||||
BEGIN
|
||||
s := NEW(Stack(Boxed.LongInt),100);
|
||||
s.Push(NEW(Boxed.LongInt,10));
|
||||
s.Push(NEW(Boxed.LongInt,100));
|
||||
Out.String("size: ");Out.Int(s.Size(),0);Out.Ln;
|
||||
Out.String("pop: ");Out.Object(s.Pop());Out.Ln;
|
||||
Out.String("top: ");Out.Object(s.Top());Out.Ln;
|
||||
Out.String("size: ");Out.Int(s.Size(),0);Out.Ln
|
||||
END Test;
|
||||
|
||||
BEGIN
|
||||
Test
|
||||
END Stacks.
|
||||
83
Task/Stack/Oberon-2/stack-2.oberon-2
Normal file
83
Task/Stack/Oberon-2/stack-2.oberon-2
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
MODULE Stacks; (** AUTHOR ""; PURPOSE ""; *)
|
||||
|
||||
IMPORT
|
||||
Out := KernelLog;
|
||||
|
||||
TYPE
|
||||
Object = OBJECT
|
||||
END Object;
|
||||
|
||||
Stack* = OBJECT
|
||||
VAR
|
||||
top-,capacity-: LONGINT;
|
||||
pool: POINTER TO ARRAY OF Object;
|
||||
|
||||
PROCEDURE & InitStack*(capacity: LONGINT);
|
||||
BEGIN
|
||||
SELF.capacity := capacity;
|
||||
SELF.top := -1;
|
||||
NEW(SELF.pool,capacity)
|
||||
END InitStack;
|
||||
|
||||
PROCEDURE Push*(a:Object);
|
||||
BEGIN
|
||||
INC(SELF.top);
|
||||
ASSERT(SELF.top < SELF.capacity,100);
|
||||
SELF.pool[SELF.top] := a
|
||||
END Push;
|
||||
|
||||
PROCEDURE Pop*(): Object;
|
||||
VAR
|
||||
r: Object;
|
||||
BEGIN
|
||||
ASSERT(SELF.top >= 0);
|
||||
r := SELF.pool[SELF.top];
|
||||
DEC(SELF.top);RETURN r
|
||||
END Pop;
|
||||
|
||||
PROCEDURE Top*(): Object;
|
||||
BEGIN
|
||||
ASSERT(SELF.top >= 0);
|
||||
RETURN SELF.pool[SELF.top]
|
||||
END Top;
|
||||
|
||||
PROCEDURE IsEmpty*(): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN SELF.top < 0
|
||||
END IsEmpty;
|
||||
|
||||
END Stack;
|
||||
|
||||
BoxedInt = OBJECT
|
||||
(Object)
|
||||
VAR
|
||||
val-: LONGINT;
|
||||
|
||||
PROCEDURE & InitBoxedInt*(CONST val: LONGINT);
|
||||
BEGIN
|
||||
SELF.val := val
|
||||
END InitBoxedInt;
|
||||
|
||||
END BoxedInt;
|
||||
|
||||
PROCEDURE Test*;
|
||||
VAR
|
||||
s: Stack;
|
||||
bi: BoxedInt;
|
||||
obj: Object;
|
||||
BEGIN
|
||||
NEW(s,10); (* A new stack of ten objects *)
|
||||
NEW(bi,100);s.Push(bi);
|
||||
NEW(bi,102);s.Push(bi);
|
||||
NEW(bi,104);s.Push(bi);
|
||||
Out.Ln;
|
||||
Out.String("Capacity:> ");Out.Int(s.capacity,0);Out.Ln;
|
||||
Out.String("Size:> ");Out.Int(s.top + 1,0);Out.Ln;
|
||||
obj := s.Pop(); obj := s.Pop();
|
||||
WITH obj: BoxedInt DO
|
||||
Out.String("obj:> ");Out.Int(obj.val,0);Out.Ln
|
||||
ELSE
|
||||
Out.String("Unknown object...");Out.Ln;
|
||||
END (* with *)
|
||||
END Test;
|
||||
END Stacks.
|
||||
3
Task/Stack/PowerShell/stack-1.psh
Normal file
3
Task/Stack/PowerShell/stack-1.psh
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
$stack = New-Object -TypeName System.Collections.Stack
|
||||
# or
|
||||
$stack = [System.Collections.Stack] @()
|
||||
1
Task/Stack/PowerShell/stack-2.psh
Normal file
1
Task/Stack/PowerShell/stack-2.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
1, 2, 3, 4 | ForEach-Object {$stack.Push($_)}
|
||||
1
Task/Stack/PowerShell/stack-3.psh
Normal file
1
Task/Stack/PowerShell/stack-3.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
$stack -join ", "
|
||||
1
Task/Stack/PowerShell/stack-4.psh
Normal file
1
Task/Stack/PowerShell/stack-4.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
$stack.Pop()
|
||||
1
Task/Stack/PowerShell/stack-5.psh
Normal file
1
Task/Stack/PowerShell/stack-5.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
$stack -join ", "
|
||||
1
Task/Stack/PowerShell/stack-6.psh
Normal file
1
Task/Stack/PowerShell/stack-6.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
$stack.Peek()
|
||||
1
Task/Stack/PowerShell/stack-7.psh
Normal file
1
Task/Stack/PowerShell/stack-7.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
$stack
|
||||
12
Task/Stack/Rust/stack-1.rust
Normal file
12
Task/Stack/Rust/stack-1.rust
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
fn main() {
|
||||
let mut stack = Vec::new();
|
||||
stack.push("Element1");
|
||||
stack.push("Element2");
|
||||
stack.push("Element3");
|
||||
|
||||
assert_eq!(Some(&"Element3"), stack.last());
|
||||
assert_eq!(Some("Element3"), stack.pop());
|
||||
assert_eq!(Some("Element2"), stack.pop());
|
||||
assert_eq!(Some("Element1"), stack.pop());
|
||||
assert_eq!(None, stack.pop());
|
||||
}
|
||||
109
Task/Stack/Rust/stack-2.rust
Normal file
109
Task/Stack/Rust/stack-2.rust
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
type Link<T> = Option<Box<Frame<T>>>;
|
||||
|
||||
pub struct Stack<T> {
|
||||
head: Link<T>,
|
||||
}
|
||||
struct Frame<T> {
|
||||
elem: T,
|
||||
next: Link<T>,
|
||||
}
|
||||
|
||||
/// Iterate by value (consumes list)
|
||||
pub struct IntoIter<T>(Stack<T>);
|
||||
impl<T> Iterator for IntoIter<T> {
|
||||
type Item = T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.pop()
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate by immutable reference
|
||||
pub struct Iter<'a, T: 'a> {
|
||||
next: Option<&'a Frame<T>>,
|
||||
}
|
||||
impl<'a, T> Iterator for Iter<'a, T> { // Iterate by immutable reference
|
||||
type Item = &'a T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.next.take().map(|frame| {
|
||||
self.next = frame.next.as_ref().map(|frame| &**frame);
|
||||
&frame.elem
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate by mutable reference
|
||||
pub struct IterMut<'a, T: 'a> {
|
||||
next: Option<&'a mut Frame<T>>,
|
||||
}
|
||||
impl<'a, T> Iterator for IterMut<'a, T> {
|
||||
type Item = &'a mut T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.next.take().map(|frame| {
|
||||
self.next = frame.next.as_mut().map(|frame| &mut **frame);
|
||||
&mut frame.elem
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T> Stack<T> {
|
||||
/// Return new, empty stack
|
||||
pub fn new() -> Self {
|
||||
Stack { head: None }
|
||||
}
|
||||
|
||||
/// Add element to top of the stack
|
||||
pub fn push(&mut self, elem: T) {
|
||||
let new_frame = Box::new(Frame {
|
||||
elem: elem,
|
||||
next: self.head.take(),
|
||||
});
|
||||
self.head = Some(new_frame);
|
||||
}
|
||||
|
||||
/// Remove element from top of stack, returning the value
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
self.head.take().map(|frame| {
|
||||
let frame = *frame;
|
||||
self.head = frame.next;
|
||||
frame.elem
|
||||
})
|
||||
}
|
||||
|
||||
/// Get immutable reference to top element of the stack
|
||||
pub fn peek(&self) -> Option<&T> {
|
||||
self.head.as_ref().map(|frame| &frame.elem)
|
||||
}
|
||||
|
||||
/// Get mutable reference to top element on the stack
|
||||
pub fn peek_mut(&mut self) -> Option<&mut T> {
|
||||
self.head.as_mut().map(|frame| &mut frame.elem)
|
||||
}
|
||||
|
||||
/// Iterate over stack elements by value
|
||||
pub fn into_iter(self) -> IntoIter<T> {
|
||||
IntoIter(self)
|
||||
}
|
||||
|
||||
/// Iterate over stack elements by immutable reference
|
||||
pub fn iter<'a>(&'a self) -> Iter<'a,T> {
|
||||
Iter { next: self.head.as_ref().map(|frame| &**frame) }
|
||||
}
|
||||
|
||||
/// Iterate over stack elements by mutable reference
|
||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
||||
IterMut { next: self.head.as_mut().map(|frame| &mut **frame) }
|
||||
}
|
||||
}
|
||||
|
||||
// The Drop trait tells the compiler how to free an object after it goes out of scope.
|
||||
// By default, the compiler would do this recursively which *could* blow the stack for
|
||||
// extraordinarily long lists. This simply tells it to do it iteratively.
|
||||
impl<T> Drop for Stack<T> {
|
||||
fn drop(&mut self) {
|
||||
let mut cur_link = self.head.take();
|
||||
while let Some(mut boxed_frame) = cur_link {
|
||||
cur_link = boxed_frame.next.take();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Task/Stack/Standard-ML/stack-1.ml
Normal file
16
Task/Stack/Standard-ML/stack-1.ml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
signature STACK =
|
||||
sig
|
||||
type 'a stack
|
||||
exception EmptyStack
|
||||
|
||||
val empty : 'a stack
|
||||
val isEmpty : 'a stack -> bool
|
||||
|
||||
val push : ('a * 'a stack) -> 'a stack
|
||||
val pop : 'a stack -> 'a stack
|
||||
val top : 'a stack -> 'a
|
||||
val popTop : 'a stack -> 'a stack * 'a
|
||||
|
||||
val map : ('a -> 'b) -> 'a stack -> 'b stack
|
||||
val app : ('a -> unit) -> 'a stack -> unit
|
||||
end
|
||||
22
Task/Stack/Standard-ML/stack-2.ml
Normal file
22
Task/Stack/Standard-ML/stack-2.ml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
structure Stack :> STACK =
|
||||
struct
|
||||
type 'a stack = 'a list
|
||||
exception EmptyStack
|
||||
|
||||
val empty = []
|
||||
|
||||
fun isEmpty st = null st
|
||||
|
||||
fun push (x, st) = x::st
|
||||
|
||||
fun pop [] = raise EmptyStack
|
||||
| pop (x::st) = st
|
||||
|
||||
fun top [] = raise EmptyStack
|
||||
| top (x::st) = x
|
||||
|
||||
fun popTop st = (pop st, top st)
|
||||
|
||||
fun map f st = List.map f st
|
||||
fun app f st = List.app f st
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue