Download presentation
Presentation is loading. Please wait.
Published byMagdalene Elaine White Modified over 9 years ago
1
Lecture 10: Finishing Off
2
Overview Stacks, Queues, Lists Generics More about Exceptions Sorting Techniques
3
A Stack A stack is an ADT designed to store values It functions like a tray dispenser in a cafeteria LIFO: Last in, First out – take from the top of the stack FILO: First in, Last out – stuff gets pushed to the bottom Stacks have two main interface methods: 1. push() : add something to the top of the stack 2. pop() : take something off of the stack
4
An Integer Stack ADT public class stack { private int tos; // Top of stack private int[] data; // The pile of integers we store public stack (int size) { // Constructor data = new int[size]; tos = 0; } public void push(int val) { // Interface method to add item data[tos++] = val; } public int pop () { // Interface method to remove item return (data[--tos]); } } // end class stack
5
Queues A Queue is an ADT that functions like a bank line-up. Where a stack was FILO (first in, last out), a queue is FIFO (first in, first out) Instead of push() and pop(), the interface methods are enqueue() and dequeue() We usually implement a queue using a "circular array" That is, when we hit the back of the array, we wrap around and back to the front of the array Use two variables: 1. Index of the front of the queue (next to remove) 2. Index of the back of the queue (where to add next item)
6
Exercise Implement a queue given the following interface: public interface FIFO { public void enqueue(int val) throws Exception; public int dequeue() throws Exception; public int count(); } count returns the number of items currently in the queue. Add a constructor that initialises an empty queue to a provided size (Note: interfaces in Java can't contain constructors).
7
Solution public class queue implements FIFO {public int count() { private int numItems, head, tail; return (numItems); private int[] data;} public void enqueue(int val) throws Exception {public queue (int size) { if (numItems == data.length) data = new int[size]; throw new Exception ("Overflow"); head = 0; tail = 0; data[tail++] = val; numItems = 0; numItems += 1;} tail = tail % data.length; } public int dequeue() throws Exception { int v; if (numItems == 0) throw new Exception ("Underflow"); v = data[head++]; head = head % data.length; numItems -= 1; return (v); } } // end class queue
8
Lists Arrays are fixed length – if we want to change the size we make a new array of the correct size and copy the values from the old array Lists are a variable length data structure that adjusts to hold more or less as required Java provides a class called ArrayList (Ch. 12) for when we want variable length arrays Also, when we defined our stack, we defined it for int, we would need a different version for String ArrayLists can be created for ANY class type
9
New Syntax! Optional (Ch. 12) – Not responsible for this on exam Only works for classes/objects, not for primitive types like int, double (uses inclusion polymorphism) ArrayList myList = new ArrayList (); Note: Second " String " is optional in Java 7.0+ E.g., ArrayList myList = new ArrayList<>(); See Fig 12.1 for listing of class methods
10
Using a List – A Stack import java.util.ArrayList; public class stack2 { private ArrayList data; public stack2 () { // Constructor data = new ArrayList (); } public void push(String val) { data.add(0, val); // add as index value 0 } public String pop () { return (data.remove(0)); // remove index value 0 } } // end class stack2
11
Using a List – A Queue import java.util.ArrayList; public class queue2 { private ArrayList data; public queue2 () { // Constructor data = new ArrayList (); } public void enqueue(String val) { data.add(val); } public String dequeue () { return (data.remove(0)); } public int count () { return data.size(); } } // end class queue2
12
Exploiting Polymorphism To really improve our queue, lets just store Objects EVERY class is a descendent of Object in Java, so we can store any class in the queue Use wrapper classes (e.g., Integer for int ) to store primitive types
13
A Polymorphic Queue import java.util.ArrayList; public class polyqueue { private ArrayList data; public polyqueue () { // Constructor data = new ArrayList (); } public void enqueue(String val) { data.add(val); } public void enqueue(int val) { data.add(new Integer(val)); } public String sDequeue () { return ((String) data.remove(0)); } public int iDequeue() { return(((Integer) data.remove(0)).intValue()); } public int count () { return data.size(); } } // end class polyqueue
14
Using our polyqueue public class driver { public static void main (String[] a) { polyqueue q = new queue(); q.enqueue("Hello"); q.enqueue("world"); System.out.printf("%s %s!\n", q.sDequeue(), q.sDequeue()); q.enqueue(7); q.enqueue(3); System.out.printf("7 + 3 = %d\n", (q.iDequeue() + q.iDequeue())); } // end main() } // end class driver
15
Generics (Section 12.4) A generic class is a parameterised class When we instantiate ArrayList, we have to specify what type we wish to instantiate it for We say that an ArrayList has a type as its parameter We can parameterise any class that we will want to make different versions for different types The types must always be objects We can use wrapper classes when we want to store int, double, etc.
16
An Example public class Pair { private type v1, v2; public void setFirst (type value) { v1 = value; } public void setSecond(type value) { v2 = value; } public type first() { return (v1); } public type second() { return (v2); } } // end class Pair
17
Using a Generic We provide a type when we instantiate the class to create an object The object we get is specialised for the type we give it Pair ip = new Pair (); Pair sp = new Pair ();
18
Exercise A integer is prime if it is greater than 1 and its only divisors are 1 and itself. That is, a number, n, cannot be evenly divided (no remainder) by any 1 < value < n. Write a method called isPrime(int n) that returns true if n is prime and false otherwise.
19
Solution public boolean isPrime (int n) { int root = (int) Math.sqrt(n); for (int i = 2; i <= root; i++) { if ((n % i) == 0) return false; } return true; }
20
More on Exceptions Exceptions are objects i.e., an exception is an instance of class Exception The class Exception can be extended e.g., IOException, EOFException We can define our own exceptions by extending Exception
21
Example public class underflow extends Exception { public underflow() { super("Empty ADT. Cannot remove item."); } public underflow(String msg) { super(msg); }
22
Notes Best to create our own exceptions so we can tell them apart from other exceptions Do not override getMessage() Generally you only need to provide the two constructors (one with a String parameter, one without) You can build your own hierarchies of exceptions if you want
23
Predefined Exceptions (see Fig. 9.1)
24
Runtime Exceptions Exceptions may be checked or unchecked Unchecked exceptions are called runtime exceptions They do not need to be to be caught You can catch them if you wish Best practice is to fix the code so they are not thrown rather than trying to catch them They are thrown by predefined library classes E.g., ArrayIndexOutOfBoundsException Any uncaught exception causes the program to terminate and exit
25
Errors Errors are kind of like exceptions You should not attempt to catch them or even try to fix them E.g., how do you fix an OutOfMemoryError when the JVM doesn't have enough memory to actually run? It is good to know that they exist, but unless you are writing "mission critical" code, errors can be generally ignored
26
Multiple Catches It is possible to have more than one catch block for a try block We can have a different catch for each type of exception and then handle each exception differently If more than one catch matches the exception, the first one is used catch blocks must differ in their parameter type
27
Example stack s = new stack(); int i; try { i = s.pop(); } catch (underflow e) { // only catches underflow Exceptions System.out.println("Stack Underflow occurred."); i = 0; } catch (Exception e) { // catches any Exception, including underflow System.out.println(e.getMessage()); }
28
Exceptions are subtypes A subtype can be used anywhere its parent can be used catch (Exception e) will catch anything of type Exception and ALL of its subclasses/subtypes catch (underflow e) will catch anything of type underflow, and its subclasses (none yet), but not its parent (the class Exception )
29
finally A finally block occurs after all the catch blocks A finally block is not very useful most of the time It is being mentioned simply because it is in the textbook, you will probably never need it The finally block is executed 1. After the try block completes 2. After a catch block completes 3. If no catch is made – normally, the method does not complete for uncaught exceptions, but a finally block is always executed before the method ends
30
finally try {...stuff that can cause exceptions... } catch (IOException ioe) {...stuff to do when something goes wrong... } finally {...stuff after try or catch finishes......also performed for uncaught exceptions BEFORE the method ends... }...stuff after try or catch finishes...
31
Repeating Code boolean success; do { try { myMethod(); success = true; } catch (Exception e) { success = false; } } while (!success);
32
Exercise Implement the following interface public interface coin { // returns "heads" or "tails" public String toString(); // randomly determines value // that toString will return public void flip(); }
33
Solution import java.util.Random; public class penny implements coin { private String[] faces = {"heads", "tails"}; private int value; // 0 or 1 private Random flipper; public penny() { flipper = new Random(); this.flip(); } public void flip() { value = flipper.nextInt(2); } public String toString() { return (faces[value]); } } // end class coin
34
Sorting How do we sort things? What algorithm should we use? There are actually many: Bubble, Radix, Selection, Insertion, Merge, and Quick sorts are the main ones They vary in their efficiency and properties Most languages provide sorting methods for you so you don't need to create these However, it is important to know them (if you go on in programming) and how they work
35
Some Assumptions Going to sort arrays of int but nothing changes except the comparator (i.e., < ) for other types The array has no unused elements We need a swap() method public static void swap (int[] data, int i, int j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } // end swap()
36
Bubble Sort In bubble sort we compare side by side elements Swap them if they are out of order The first pass over the array will get the largest to the last index The second pass gets the second largest into the second last index (we don't look at the last) We keep doing this and stopping one index value earlier each time until the smallest is all that remains in the first index Its kind of inefficient, but its simple to program and it works
37
The Code public static void bsort (int[] data) { for (int lg = data.length-1; lg > 0; lg--) { for (int i = 0; i < lg; i++) { if (data[i] > data[i+1]) { swap (data, i, i+1); } } // end bsort()
38
Selection Sort We can do a bit better than this in a way that isn't so inefficient On pass one we find the smallest value swap it with the value in the first index On pass two we find the smallest value (that remains) and swap it with the value in the second index We repeat this until there is only one value left, the largest value in the last index
39
The Code public static void ssort (int[] data) { int i, minIndex; for (i = 0; i < data.length; i++) { minIndex = min(data, i, COUNT-1); swap(data, i, minIndex); } } // end ssort()
40
Finding the index of the min value // Only searches the range lo..hi inclusive public static int min (int[] data, int lo, int hi) { int minIndex = lo; int minVal = data[lo]; for (int i = lo + 1; i <= hi; i++) { if (data[i] < minVal) { minVal = data[i]; minIndex = i; } return (minIndex); } // end min()
41
Quick Sort The most complicated, but proven as the most efficient in most cases Idea: 1. Pick a value – we call this the pivot 2. Divide the data into two groups: pivot 3. Quick sort each group 4. Join the groups: pivot
42
The Code Part 1 public static int[] qsort (int[] values) { // Check for null, empty, or singleton array if ((values == null) || (values.length <= 1) || (size <= 1)) { return (values); } // Not empty, call overloaded version qsort(values, 0, size - 1); return (values); }
43
The Code Part 2 public static void qsort(int[] numbers, int low, int high) { int i = low, j = high; // Get the pivot element from the middle of the list int pivot = numbers[(high + low)/2]; // Divide into two lists while (i <= j) { // Find item on LHS to exchange while (numbers[i] < pivot) { i++; } // Find item on RHS to exchange while (numbers[j] > pivot) { j--; } // Swap if on wrong sides of pivot if (i <= j) { swap(numbers, i++, j--); } // Sort sub-arrays if (low < j) qsort(numbers, low, j); if (i < high) qsort(numbers, i, high); } // end qsort()
44
Exercise Write a method called union() that takes two arrays of integers and returns a new array that only has integers that are in both arrays. Do not worry about wasting space – you can fill any unused array elements with 0 e.g. union([1,2,3],[5,4,3,2]) returns [2,3]
45
Solution public boolean member(int[] s, int n) { for (int i = 0; i < s.length; i++) { if (s[i] == n) return (true); } return (false); } public int[] union(int[] s1, int[] s2) { int[] s3 = new int[s1.length]; int i, j = 0; for (i = 0; i < s3.length; i++) s3[i] = 0; for (i = 0; i < s1.length; i++) { if (member(s2, s1[i])) s3[j++] = s1[i]; } return (s3); }
46
Returning Multiple Values If we want a method to return more than one value we have several options 1. If they are the same type (e.g., both int) we could use an array 2. Sometimes we can combine them, return them, and then them apart e.g., concatenate two strings with a symbol between them so we know where to break them into two strings later 3. We can create a new object that stores the values and returns that (no limitations, always works)
47
Example 1 public static String[] getNames1() { String[] names = new String[2]; Scanner s = new Scanner (System.in); System.out.print("First name: "); names[0] = s.next(); System.out.print("Last name: "); names[1] = s.next(); return (names); }
48
Application 1 String[] names = getNames1(); System.out.printf("%s %s\n", names[0], names[1]); Requires the user of getNames1() to know that the first name is in index 0 and the last name is in index 1
49
Example 2 public static String getNames2() { Scanner s = new Scanner (System.in); System.out.print("First name: "); String n1 = s.next(); System.out.print("Last name: "); String n2 = s.next(); return (n1 + "&" + n2); }
50
Application 2 String names = getNames2(); int marker = names.indexOf("&"); System.out.printf("%s %s\n", names.substring(0,marker), names.substring(marker+1)); Requires the user of getNames2() to know that the names are separated by the character &
51
Example 3 public class fullname { String first, last; } public static fullname getNames3() { fullname n = new fullname(); Scanner s = new Scanner (System.in); System.out.print("First name: "); n.first = s.next(); System.out.print("Last name: "); n.last = s.next(); return (n); }
52
Application 3 fullname n = getNames3(); System.out.printf("%s %s\n", n.first, n.last); Requires the user of getNames3() to know that the details of the class fullname
53
Are we all sorted out now?
54
To Do Prepare for the final exam Program, Program, Program Do Assignment 10 in the lab today CHANGE: You may bring as many pages as you want of HANDWRITTEN notes to the final exam! No 2 page limit now exists. Make all the notes you want
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.