Download presentation
Presentation is loading. Please wait.
1
ITI 1221. Introduction to Computing II Lab-12
Dewan Tanvir Ahmed University of Ottawa
2
Today’s Objective Further understanding of iterators
Further understanding of recursive list processing Assignment 5
3
Introduction A class to store an unlimited number of bits:
zeros and ones. This class, called BitList, is a linked list to store the bits.
4
BitList Because most operations on bits work from right to left
Your implementation must store the bits in the “right-to-left” order — with the rightmost bit in the first node of the list. For example, the bits “11010” must be stored in a list such that -> 0 -> 1 -> 0 -> 1 -> 1
5
BitList (cont..) Complete the implementation of the class BitList.
public BitList( String s ); creates a list of bits representing the input string s. The given string, s, must be a string of 0s and 1s, otherwise the constructor must throw an exception of type IllegalArgumentException. This constructor initializes the new BitList instance to represent the value in the string. Each character in the string represents one bit of the list, with the rightmost character in the string being the low order bit.
6
BitList (cont..) For example, given the string “ ” the constructor should initialize the new BitList to include this list of bits: -> 1 -> 1 -> 1 -> 0 -> 1 -> 0 -> 1 If given the empty string, the constructor should create an empty list — null is a not a valid argument. The constructor must not remove the leading zeroes. For example, given “0001” the constructor must create a list of size 4: -> 1 -> 0 -> 0 -> 0
7
Class Node private static class Node { private int bit; // <- NEW
private Node next; private Node( int bit, Node next ) { // <- ACCORDINGLY ... this.bit = bit; this.next = next; }
8
BitList public class BitList { // useful constants
public static final int ZERO = 0; public static final int ONE = 1; // instance variables private Node first; // constructors public BitList() { first = null; }
9
BitList (cont..) public BitList( String s ) { // pre-condition
if ( s == null ) { throw new IllegalArgumentException( "null" ); } for ( int i=0; i < s.length() ; i++ ) { int bit = s.charAt(i) - '0'; if ( ( bit != ZERO ) && ( bit != ONE ) ) throw new IllegalArgumentException( s ); addFirst( bit ); // reverses the order!
10
BitList (cont..) public void addFirst( int bit ) {
if ( ( bit != ZERO ) && ( bit != ONE ) ) { throw new IllegalArgumentException( Integer.toString( bit ) ); } first = new Node( bit, first );
11
BitList (cont..) public int removeFirst() { if ( first == null ) {
throw new NoSuchElementException(); } int saved = first.bit; first = first.next; return saved;
12
BitList (cont..) public String toString() { String str = "";
if ( first == null ) { str += ZERO; } else { Node p = first; while ( p!=null ) { str = p.bit + str; // reverses the order! p = p.next; } return str;
13
BitList (cont..) public Iterator iterator() {
return new BitListIterator(); }
14
BitListIterator private class BitListIterator implements Iterator {
private Node current = null; private BitListIterator() { current = null; } public boolean hasNext() { return ( ( current == null && first != null ) || ( current != null && current.next != null ) );
15
BitListIterator (cont..)
public int next() { if ( current == null ) { current = first ; } else { current = current.next ; // move the cursor forward } throw new NoSuchElementException() ; return current.bit ;
16
BitListIterator (cont..)
public void add( int bit ) { if ( ( bit != ZERO ) && ( bit != ONE ) ) { throw new IllegalArgumentException( Integer.toString( bit ) ); } Node newNode; if ( current == null ) { first = new Node( bit, first ); current = first; } else { current.next = new Node( bit, current.next ); current = current.next;
17
Iterative Create a class called Iterative.
Implement the methods below. Your solutions must be iterative uses iterators
18
Iterative (cont..) - Complement
static BitList complement( BitList in ) Write a static iterative method that returns a new BitList that is the complement of its input. The complement of 0 is 1, and vice-versa. The complement of a list of bits is a new list such that each bit is the complement of the bit at the same position in the original list. Here are 4 examples. 1011 0100 0 1 01 10
19
Iterative (cont..) - Complement
public static BitList complement( BitList in ) { BitList result; result = new BitList(); Iterator i = in.iterator(); Iterator j = result.iterator(); if ( ! i.hasNext() ) { j.add( BitList.ONE ); } else { while ( i.hasNext() ) { int bit = i.next(); if ( bit == BitList.ONE ) { j.add( BitList.ZERO ); } return result;
20
Iterative (cont..) - or static BitList or( BitList a, BitList b )
Write a static iterative method that returns the or of two BitLists. This is a list of the same length as a and b such that each bit is the or of the bits at the equivalent position in the lists a and b. It throws an exception, IllegalArgumentException, if either list is empty or the lists are of different lengths. a = 10001 b = 00011 a or b = 10011
21
Iterative (cont..) public static BitList or( BitList a, BitList b ) {
BitList result; result = new BitList(); Iterator i = a.iterator(); Iterator j = b.iterator(); Iterator k = result.iterator(); if ( ! i.hasNext() ) { throw new IllegalArgumentException( "a is empty" ); } if ( ! j.hasNext() ) { throw new IllegalArgumentException( "b is empty" ); while ( i.hasNext() ) { if ( ! j.hasNext() ) { throw new IllegalArgumentException( "b is shorter than a" ); } int iBit = i.next(); int jBit = j.next(); if ( iBit == BitList.ONE || jBit == BitList.ONE ) { k.add( BitList.ONE ); } else { k.add( BitList.ZERO ); if ( j.hasNext() ) { throw new IllegalArgumentException( "b is longer than a" ); return result;
22
Recursive list processing
For this part of the laboratory you must write recursive implementations of the methods inside the class BitList.
23
Recursive list processing (cont..)
void complement() Write the instance method complement() for/into the class BitList. It transforms this list changing each bit to its complement. a = new BitList( "10001" ); System.out.println( a ); -> 10001 a.complement(); System.out.println( a ); -> 01110
24
Recursive list processing (cont..)
public void complement() { if ( first == null ) { addFirst( ONE ); } else { complement( first ); }
25
Recursive list processing (cont..)
private void complement( Node p ) { // base case if ( p == null ) { return; } // pre-processing (could be post as well) if ( p.bit == ONE ) { p.bit = ZERO; } else { p.bit = ONE; // recursion complement( p.next );
26
Recursive list processing (cont..)
BitList or( BitList other ) Write an instance method that returns a new BitList that is the or of this list and the argument other. This list and other remain unchanged. a = new BitList( "10001" ); b = new BitList( "00011" ); c = a.or( b ); System.out.println( a ); -> 10001 System.out.println( b ); -> 00011 System.out.println( c ); -> 10011
27
Recursive list processing (cont..)
public BitList or( BitList other ) { if ( first == null ) { throw new IllegalArgumentException( "this list is empty" ); } if ( other.first == null ) { throw new IllegalArgumentException( "other is empty" ); BitList result; result = new BitList(); or( result, first, other.first ); return result;
28
Recursive list processing (cont..)
private void or( BitList result, Node p, Node q ) { // pre-conditions if ( p == null && q != null ) { throw new IllegalArgumentException( "this list is shorter" ); } if ( p != null && q == null ) { throw new IllegalArgumentException( "this list is longer" ); // base case if ( p == null && q == null ) { return; // recursion or( result, p.next, q.next ); // post-processing if ( p.bit == ONE || q.bit == ONE ) { result.addFirst( ONE ); } else { result.addFirst( ZERO );
29
Recursive list processing (cont..)
boolean equals( Object other ) Implement the method boolean equals( Object other ) that returns true if other designates a BitList, of the same size, and such that the bits at the same position in both lists are the same, and false otherwise. The implementation must be recursive. Here are examples: a = 11001 b = 11001 a.equals( b ) -> true a = 11001 b = 11000 a.equals( b ) -> false
30
Recursive list processing (cont..)
public boolean equals( Object other ) { if ( ! ( other instanceof BitList ) ) { return false; } return equals( first, ( (BitList) other ).first );
31
Recursive list processing (cont..)
private static boolean equals( Node p, Node q ) { // Base cases (stopping recursion) // Same length? if ( p == null && q != null ) { return false; } if ( p != null && q == null ) { // Reached the end of both lists? if ( p == null && q == null ) { return true; // Found a mismatch? if ( p.bit != q.bit ) { // General case return equals( p.next, q.next );
32
Assignment 5 Objectives
Introduction to recursive list processing inside the class Familiarity with recursive list processing outside the class Introduction to binary search trees and traversing a tree
33
Assignment 5 – Recursive List processing
Inside the class LinkedList provided, write the recursive instance method foldl. The method foldl applies the given operator to the first two elements of the list to produce a first intermediate result, it then applies the operator to the intermediate result and the third element to produce a new intermediate result, and so on. The operator is always applied to the intermediate result and the next element of the list to produce a new intermediate result for the next step in the calculation. The smallest valid list is a list of two elements. Here the operator Plus is applied to a list that contains the integers 1 and 2 (in that order). The final result is the integer 3. LinkedList xs = new LinkedList(); xs.addLast( new Integer( 1 ) ); xs.addLast( new Integer( 2 ) ); Integer result = (Integer) xs.foldl( new Plus() );
34
Assignment 5 – Recursive List processing
For the next example, the operator Maximum is applied to a list that contains the integers 10, 0, 15 and 5 (in that order). LinkedList xs = new LinkedList(); xs.addLast( new Integer( 10 ) ); xs.addLast( new Integer( 0 ) ); xs.addLast( new Integer( 15 ) ); xs.addLast( new Integer( 5 ) ); Integer result = (Integer) xs.foldl( new Maximum() );
35
Assignment 5 – Recursive List processing
LinkedList xs = new LinkedList(); xs.addLast( "a" ); xs.addLast( "b" ); xs.addLast( "c" ); xs.addLast( "d" ); xs.addLast( "e" ); xs.addLast( "f" ); xs.addLast( "g" ); xs.addLast( "h" ); System.out.println( xs.foldl( new Concat() ) ); Finally, the above statements are producing the following output: “a,b,c,d,e,f,g,h”.
36
Assignment 5 – Recursive List processing
Write a recursive implementation of the instance method foldl described above. You must use the technique presented in class where a public method initiates the first call to the recursive static private method. Write a class And that implements the interface Operator. Its method apply( Object a, Object b ) assumes that both arguments are Boolean and returns the and of the two arguments (i.e. returns a Boolean representing the value true if both arguments are true and false otherwise). Write a class Product that implements the interface Operator. Its method apply( Object a, Object b ) returns the product of its two arguments. Write a class Join that implements the interface Operator. Its method apply( Object a, Object b ) returns a new Linkedlinked which is the concatenation if its two LinkedList arguments — the two arguments remain unchanged by the call.
37
Assignment 5 – Recursive list processing revisited
The method you write for this question must be recursive, and must be static (class) methods placed in the class (A5P2.java). Therefore, you must use the technique seen in class for implementing recursive methods outside of the class.
38
Assignment 5 – Recursive list processing revisited
add( LinkedList l, Comparable object ) (25 marks) Write a recursive method add( LinkedList l, Comparable obj ). The method first checks that l is non-decreasing. If it is not, the methode does not change l. If l is non-decreasing, the method inserts obj into l in the correct position so that the result is still non-decreasing.
39
Assignment 5 – Recursive list processing revisited
For example, suppose l is 17.2 -> 18.1 -> 18.1 -> 22 add( l, new Double( 99 ) ) would add 99 at the end of l; add( l, new Double( -5 ) ) would add -5 at the beginning of l; add( l, new Double( 19 ) ) would add 19 just before the 22; add( l, new Double( 18.1 ) ) would add another 18.1 so that there would be three consecutively (the exact position of the new one doesn’t matter as long as it is adjacent to one or more of the existing ones). The overall result of these 4 operations would be -5 -> 17.2 -> 18.1 -> 18.1 -> 18.1 -> 19 -> 22 -> 99
40
Binary search tree This part of the assignment is about the implementation of a binary search tree seen in class. LinkedList toListInOrder() (25 marks) Inside the class BinarySearchTree, write the method LinkedList toListInOrder() that returns a list of all the values stored in the tree. The method must implement an in-order traversal of the tree.
41
The End
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.