300 likes | 401 Views
Week 3 – Sorting Machine, Stacks, Recursion, and Partial Maps. Jimmy Voss Disclaimer: Not all material is original. Some is taken from the official course slides, and some is taken from Anna’s slides. Sorting Machine Idea. Container class for sorting arbitrary Items.
E N D
Week 3 – Sorting Machine, Stacks, Recursion, and Partial Maps Jimmy Voss Disclaimer: Not all material is original. Some is taken from the official course slides, and some is taken from Anna’s slides.
Sorting Machine Idea • Container class for sorting arbitrary Items. • Should work with any sorting algorithm. • Works in 2 stages: • Insertion phase – place items into a sorting machine. While in insertion phase, inserting is true. • Extraction phase – remove sorted items from Sorting Machine. • Note: We make Sorting Machine a Separate component / class.
Why A Separate Component? • Sorting_Machine will be templated • Allows for basic logic of a particular sort to be implemented regardless of the type being operated on. (Template functions require messier notation for client). • Many different sorting functions are commonly used. • Allows use of Utility functions for Comparison based sorting algorithms. (General_Are_In_Order)
Sorting_Machine • Insert(x) • requires: inserting • Change_To_Extraction_Phase() • requires: inserting • Remove_First(x) • requires: not inserting, |self| > 0 • Remove_Any(x) • requires: not inserting, |self| > 0 • Size() • Is_In_Extraction_Phase()
Sorting Machine Usage • Typical program flow: • Insert all objects you want sorted one at a time. • Call Change_To_Extraction_Phase() • A boolean flag maintains whether this has been called. • After this has been called, insertion phase is done. • Repeatedly call Remove_First() to get elements in sorted order.
Sorting Machine Templates abstract_template < concrete_instanceclass Item, concrete_instanceutility_classItem_Are_In_Order /*! implements abstract_instanceGeneral_Are_In_Order <Item> !*/ > class Sorting_Machine_Kernel { /* Declarations and Specs */ };
Example: Integer Sorting Machine #include “/CT/Sorting_Machine/Kernel_1_C.h” #include “/CI/Integer/Integer_Are_In_Order.h” class Integer_Sorting_Machine : instantiates Sorting_Machine_Kernel_1a_C< Integer, Integer_Are_In_Order_1 > { }; Note: Integer_Are_In_Order_1 is not actually in the Resolve Library
Example: Integer Sorting Machine #include “/CT/Sorting_Machine/Kernel_1_C.h” #include “/CI/Integer/Integer_Are_In_Order.h” class Integer_Sorting_Machine : instantiates Sorting_Machine_Kernel_1a_C< Integer, Integer_Are_In_Order_1 > { }; Uses a utility class Note: Integer_Are_In_Order_1 is not actually in the Resolve Library
Exercise • Suppose you have access to a sorting_machine object instantiated to work with text objects named “sorter”. Write code for the following: global_procedureLex_Sort(alters Queue_Of_Text& sort_me); /*! ensures sort_me = permutation of #sort_me and for every a, b, c: string of string of character, i, j: string of character where (sort_me = a * <i> * b * <j> * c) (|i| <= |j| and if |i| = |j| then i < j) !*/
Exercise global_procedureLex_Sort(alters Queue_Of_Text& sort_me) { while ( sort_me.Length() > 0 ) { object catalyst Text x; sort_me.Dequeue( x ); sorter.Insert( x ); } sorter.Change_To_Extraction_Phase(); while ( sorter.Size() > 0 ) { object catalyst Text x; sorter.Remove_First( x ); sort_me.Enqueue( x ); } }
Concept of Recursion • In mathematics, recursion refers to a way of defining functions. • Example: Fibonacci sequence: Base Cases: Recursive Definition: Resulting sequence: 1, 1, 2, 3, 5, 8, 13, . . .
Recursion in Programming • Functions are said to be recursive if: • The function calls itself -- OR -- • Function calls function which after a series of function calls results in calling again. and the function terminates.
Recursion in Programming • A recursive function typically refers to a function which calls itself. • Base cases – there is some “small” case which the recursive function handles without making a recursive call. • Recursive step – The step that reduces the problem to a “smaller” problem, and uses the results of the smaller problem to solve the larger problem.
Exercise (Fibonacci) • Fill in the following function which returns the Fibonacci number with the base cases . • Assume in the below that FibonacciFunc is a math function that returns the Fibonacci number. global_function Integer Fibonacci( preserves Integer n ); /*! requires n >= 1 ensures f_n = FibonacciFunc( #n ) !*/
Exercise (Solution) global_function Integer Fibonacci( preserves Integer n ); { if ( n <= 2 ) { // base cases return 1; } else { // recursive case return Fibonacci( n-1 ) + Fibonacci( n-2 ); } } Question: Is this very efficient?
Stacks • Intuitively like a stack of objects. • LIFO – Last in first out. • Purest form has 2 operations: • Push – add an object to the stack • Pop – Take an object off the top of the stack. • Implemented as a template container class.
Stacks (Operations) • Push ( x ) • consumes x • Pop( x ) • produces x • Accessor, i.e. [current] • Look at the top element of the stack. • Length()
Stack (Mathematical Model) • Modeled as a string of Item. • Push adds an Item to the front of the string. • Pop removes an Item from the front of the string. • Accessor can be used to access the Item at the front of the string.
Stacks are Important Memory Addr • Program Layout in Virtual Memory • Program stack allocates space for function / procedure calls. • Very Easy to implement at a low level (Assembly level programming). 0 Reserved Program Code Stack Heap Large Number
Exercise: Reversing a Stack • Give a recursive implementation for the following procedure: global_procedureReverse_Queue( altersQueue_Of_Integer & myQueue ) { // fill in code here } • What is the base case? • How does one reduce the size of the problem? • Give a second implementation without recursion. Hint: use a stack.
Exercise (Recursive Solution) global_procedureReverse_Queue( altersQueue_Of_Integer& myQueue ) { // Base Case if ( myQueue.Length() <= 1 ) { // Do nothing } // Recursive Case else { object catalyst Integer x; myQueue.Dequeue( x ); Reverse_Queue( myQueue ); myQueue.Enqueue( x ); } }
Exercise (Recursive Solution Trace) myQueue = <4, 3, 2, 1> myQueue = <1, 2, 3, 4> X = 1 Reverse_Queue( myQueue) myQueue = <4, 3, 2> myQueue = <2, 3, 4> X = 2 Reverse_Queue( myQueue) myQueue = <4, 3> myQueue = <3, 4> X = 3 Reverse_Queue( myQueue) myQueue = <4> myQueue = <4>
Exercise global_procedureReverse_Queue( altersQueue_Of_Integer& myQueue ) { object catalystStack_Of_Integer S; while ( myQueue.Length() > 0 ) { object catalyst Integer temp; myQueue.Dequeue( temp ); S.Push( temp ); } while ( S.Length() > 0 ) { object catalyst Integer temp; S.Pop( temp ); myQueue.Enqueue( temp ); } }
Partial Map • A map is a data structure which maps an d_item to an r_item. • d_items are unique. • Both the index and the item mapped to are template types. • Example: Webster’s Dictionary maps each word to a set of definitions.
Examples of maps • Mathematical model: a map is a set of points (d_item, r_item) such that d_item is the index and r_item the item mapped to. Which of these are maps? • {(1, 2), (2, 2), (3, 2)} • {(1, 2), (1, 3), (3, 3)} • {(“hi”, “a greeting”), (“Tom”, “a name”), (“Tom”, “my best friend”)} • {(“hi”, {“a greeting”}), (“Tom”, {“a name”, “my best friend”})}
Examples of maps • Answers: • {(1, 2), (2, 2), (3, 2)} – Yes • {(1, 2), (1, 3), (3, 3)} – No, 1 is a d_item twice • {(“hi”, “a greeting”), (“Tom”, “a name”), (“Tom”, “my best friend”)} – No, “Tom” is a d_item twice. • {(“hi”, {“a greeting”}), (“Tom”, {“a name”, “my best friend”})} – Yes
requires d self d self |self| > 0 d self
d_item type r_item type