Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
COMPSCI 107 Computer Science Fundamentals Lecture 12 - ADTs and Stacks Chapter Three of the textbook 1 Exercise • What is the big-O value for the example function? # lecture12a.py def example(n): count = 0 i = 1 while i < n: for j in range(n): count += 1 i = i * 2 print(count) example(10) example(100) example(1000) 2 Exercise • If a particular quadratic time algorithm uses 300 elementary operations to process an input of size 10, what is the most likely number of elementary operations it will use if given an input of size 1000. A. 300,000,000 B. 3,000,000 C. 300,000 D. 30,000 E. 3,000 3 Exercise • You know that a given algorithm runs in O(2n) time. If your computer can process input of size 10,000 in one year using an implementation of this algorithm, approximately what size input could you solve in one year with a computer 1000 times faster? A. 10,100 B. 320,000 C. 10,010 D. 15,000 E. 10,000,000 4 Software Design • Modularity • • • Divide the program into smaller parts Advantages • Keeps the complexity manageable • Isolates errors (parts can be tested independently) • Can replace parts easily • Eliminates redundancies (each part takes care of own data) Easier to write, Easier to read, Easier to test, easier to modify 5 ADTs • An Abstract Data Type is a model which is defined by its behaviour. It consists of data and functions/operations. • We specify functions which work on the model. This means a person can use an ADT without knowing about its implementation. • Specifications of an ADT focus on what the functions do. • Classes are very like ADTs (and we implement ADTs in classes) but ADTs are more general (abstract) than most classes. 6 Figure 1.2: Abstract Data Type 7 Example ADTs • • Integers • Data: …, -3, -2, -1, 0, 1, 2, 3, … • Functions: +, -, ×, ÷, ordering, test for equality, … Sets • Data: an unordered collection of unique elements • Functions: add, remove, union, intersection, complement, … 8 Data Structures • A data structure is an implementation of an ADT (hence in a programming language). • • It is not really as clear cut as that. We throw the terms "data structure" and "ADT" around and sometimes mean the same thing. e.g. Python data structures are lists, sets, dictionaries, tuples, etc. 9 Different implementations Task that requires module A function calls Interface for module A Implementation X Implementation Y 10 Linear Data Structures • Items are ordered according to how they were added. • Each item has an element before it (except the first) and each item has an element after it (except the last). • There are first and last elements (unless the structure is empty). Sometimes called front and rear, top and bottom, left and right - the names don’t matter but there are two ends. • e.g. stacks, queues, deques, lists 11 Stack ADT Figure 3.1: A Stack of Books Figure 3.2: A Stack of Primitive Python Objects Figure 3.3: The Reversal Property of Stacks 12 Stack • The text uses the terms "top" and "base", I use "top" and "bottom" of the stack. • Operations happen at the "top" of the stack, items are pushed onto the top and popped off the top. • A stack is a LIFO structure, Last In First Out. • Functions - push, pop, peek (look at the top but don’t remove it), is the stack empty, how many elements in the stack? 13 Implementing a stack in Python • This is trivial because of the Python list. In reality programmers seldom use a stack class in Python because a list provides all of the operations you need, in particular the default pop function. • The advantage of a stack class is that you are not tempted to use non-stack functions on the object. 14 Standard Python stack operations on lists • create a stack - stack = [] • push - stack.append(value) • pop - stack.pop() • peek - stack[-1] • is_empty - len(stack) == 0 or stack == [] • stack size - len(stack) 15 Or a stack class # stack.py class Stack: def __init__(self): self.items = [] def is_empty(self): return self.items == [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def peek(self): return self.items[-1] def size(self): return len(self.items) def __repr__(self): return repr(self.items) 16 __repr__? • What is that __repr__ method? • It stands for representation and is supposed to produce a unique value for the object (which my version doesn’t do, but neither does the list builtin version). • It is used by the Python shell to display an object which is why I use it here so that I can see the stack in the shell. • If you don’t have an __str__ method the __repr__ method will be used for that as well. 17 What are the Big-O values of def push(self, item): self.items.append(item) def pop(self): return self.items.pop() 18 19 Another stack implementation What are the Big-O values of push and pop? class Stack: def __init__(self): self.items = [] def is_empty(self): return self.items == [] def push(self, item): self.items.insert(0, item) def pop(self): return self.items.pop(0) def peek(self): return self.items[-1] def size(self): return len(self.items) 20 Using stacks • We use stacks whenever we want to reverse things or deal with them most recent thing first. e.g. the back button in a browser. • Other uses • checking braces • converting decimal to binary representations • postfix operations (this is cool) 21 Checking braces • or parentheses and brackets - { } [ ] ( ) • We want to determine if a string has valid braces. • we push left braces onto a stack and pop them off when we hit a matching right brace • if the popped brace doesn’t match the current character the string is not valid • if we get to the end of the string and there is nothing on the stack the string was valid 22 Compare this to the one in the textbook # lecture12b.py LEFT RIGHT MATCH = "([{" = ")]}" = {")": "(", "]": "[", "}": "{"} def valid_braces(string): """Return True iff string has valid braces, parentheses etc.""" braces = [] for char in string: if char in LEFT: braces.append(char) elif char in RIGHT: if braces == [] or braces.pop() != MATCH[char]: return False return braces == [] 23