2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -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 &nbsp; <big><u>l</u>ast <u>i</u>n, <u>f</u>irst <u>o</u>ut</big> &nbsp; access policy. &nbsp; 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.
* &nbsp; ''push'' &nbsp; stores a new element onto the stack top;
* &nbsp; ''pop'' &nbsp; returns the last pushed stack element, while removing it from the stack;
* &nbsp; ''empty'' &nbsp; 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.
* &nbsp; ''top'' &nbsp; (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>

View 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
View 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

View 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.

View 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.

View file

@ -0,0 +1,3 @@
$stack = New-Object -TypeName System.Collections.Stack
# or
$stack = [System.Collections.Stack] @()

View file

@ -0,0 +1 @@
1, 2, 3, 4 | ForEach-Object {$stack.Push($_)}

View file

@ -0,0 +1 @@
$stack -join ", "

View file

@ -0,0 +1 @@
$stack.Pop()

View file

@ -0,0 +1 @@
$stack -join ", "

View file

@ -0,0 +1 @@
$stack.Peek()

View file

@ -0,0 +1 @@
$stack

View 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());
}

View 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();
}
}
}

View 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

View 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