Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Algorithms (2006)

.pdf
Скачиваний:
255
Добавлен:
17.08.2013
Размер:
9.67 Mб
Скачать

D

Answers to Exercises

The solutions provided in this appendix are sample answers. Not every chapter had exercises at the end, but it is hoped that the ones provided will give you ample opportunity to put what you’ve learned into practice. We encourage you to experiment with each chapter’s concepts.

Chapter 2

Exercises

1.Create an iterator that only returns the value of every nth element, where n is any integer greater than zero.

2.Create a predicate that performs a Boolean AND (&&) of two other predicates.

3.Re-implement PowerCalculator using recursion instead of iteration.

4.Replace the use of arrays with iterators in the recursive directory tree printer.

5.Create an iterator that holds only a single value.

6.Create an empty iterator that is always done.

Exercise 1 Solution

package com.wrox.algorithms.iteration;

public class SkipIterator implements Iterator { private final Iterator _iterator;

private final int _skip;

public SkipIterator(Iterator iterator, int skip) { assert iterator != null : “iterator can’t be null”; assert skip > 0 : “skip can’t be < 1”;

_iterator = iterator; _skip = skip;

}

public void first() { _iterator.first();

Appendix D

skipForwards();

}

public void last() { _iterator.last(); skipBackwards();

}

public boolean isDone() { return _iterator.isDone();

}

public void next() { _iterator.next(); skipForwards();

}

public void previous() { _iterator.previous(); skipBackwards();

}

public Object current() throws IteratorOutOfBoundsException { return _iterator.current();

}

private void skipForwards() {

for (int i = 0; i < _skip && !_iterator.isDone(); _iterator.next());

}

private void skipBackwards() {

for (int i = 0; i < _skip && !_iterator.isDone(); _iterator.previous());

}

}

Exercise 2 Solution

package com.wrox.algorithms.iteration;

public final class AndPredicate implements Predicate { private final Predicate _left;

private final Predicate _right;

public AndPredicate(Predicate left, Predicate right) { assert left != null : “left can’t be null”; assert right != null : “right can’t be null”;

_left = left; _right = right;

}

public boolean evaluate(Object object) {

return _left.evaluate(object) && _right.evaluate(object);

}

}

496

Answers to Exercises

Exercise 3 Solution

package com.wrox.algorithms.iteration;

public final class RecursivePowerCalculator implements PowerCalculator { public static final PowerCalculator INSTANCE = new PowerCalculator();

private RecursivePowerCalculator() {

}

public int calculate(int base, int exponent) { assert exponent >= 0 : “exponent can’t be < 0”;

return exponent > 0 ? base * calculate(base, exponent - 1) : 1;

}

}

Exercise 4 Solution

package com.wrox.algorithms.iteration;

import java.io.File;

public final class RecursiveDirectoryTreePrinter { private static final String SPACES = “ “;

public static void main(String[] args) { assert args != null : “args can’t be null”;

if (args.length != 1) {

System.err.println(“Usage: RecursiveDirectoryTreePrinter <dir>”); System.exit(4);

}

System.out.println(“Recursively printing directory tree for: “ + args[0]); print(new File(args[0]), “”);

}

private static void print(Iterator files, String indent) { assert files != null : “files can’t be null”;

for (files.first(); !files.isDone(); files.next()) { print((File) files.current(), indent);

}

}

private static void print(File file, String indent) { assert file != null : “file can’t be null”; assert indent != null : “indent can’t be null”;

System.out.print(indent);

System.out.println(file.getName());

if (file.isDirectory()) {

497

Appendix D

print(new ArrayIterator(file.listFiles()), indent + SPACES);

}

}

}

Exercise 5 Solution

package com.wrox.algorithms.iteration;

public class SingletonIterator implements Iterator { private final Object _value;

private boolean _done;

public SingletonIterator(Object value) {

assert value != null : “value can’t be null”; _value = value;

}

public void first() { _done = false;

}

public void last() { _done = false;

}

public boolean isDone() { return _done;

}

public void next() { _done = true;

}

public void previous() { _done = true;

}

public Object current() throws IteratorOutOfBoundsException { if (isDone()) {

throw new IteratorOutOfBoundsException();

}

return _value;

}

}

Exercise 6 Solution

package com.wrox.algorithms.iteration;

public final class EmptyIterator implements Iterator {

public static final EmptyIterator INSTANCE = new EmptyIterator();

private EmptyIterator() {

498

Answers to Exercises

// Nothing to do

}

public void first() { // Nothing to do

}

public void last() { // Nothing to do

}

public boolean isDone() { // We’re always done! return true;

}

public void next() { // Nothing to do

}

public void previous() { // Nothing to do

}

public Object current() throws IteratorOutOfBoundsException { throw new IteratorOutOfBoundsException();

}

}

Chapter 3

Exercises

1.Write a constructor for ArrayList that accepts a standard Java array to initially populate the

List.

2.Write an equals() method that will work for any List implementation.

3.Write a toString() method that will work for any List implementation that prints the contents as a single line with values surrounded by square brackets and separated by commas. For example, “[A, B, C]” or “[]” for an empty List.

4.Create an Iterator that will work for any List implementation. What are the performance implications?

5.Update LinkedList to traverse backwards if, when inserting and deleting, the desired index is more than halfway along the list.

6.Rewrite indexOf() so that it will work for any List.

7.Create a List implementation that is always empty and throws

UnsupportedOperationException if an attempt is made to modify it.

499

Appendix D

Exercise 1 Solution

public ArrayList(Object[] array) {

assert array != null : “array can’t be null”;

_initialCapacity = array.length; clear();

System.arraycopy(array, 0, _array, 0, array.length); _size = array.length;

}

Exercise 2 Solution

public boolean equals(Object object) {

return object instanceof List ? equals((List) object) : false;

}

public boolean equals(List other) {

if (other == null || size() != other.size()) { return false;

}

Iterator i = iterator();

Iterator j = other.iterator();

for (i.first(), j.first();

!i.isDone() && !j.isDone(); i.next(), j.next()) {

if (!i.current().equals(j.current())) { break;

}

}

return i.isDone() && j.isDone();

}

Exercise 3 Solution

public String toString() {

StringBuffer buffer = new StringBuffer();

buffer.append(‘[‘);

if (!isEmpty()) {

Iterator i = iterator();

for (i.first(); !i.isDone(); i.next()) { buffer.append(i.current()).append(“, “);

}

buffer.setLength(buffer.length() - 2);

500

Answers to Exercises

}

buffer.append(‘]’);

return buffer.toString();

}

Exercise 4 Solution

package com.wrox.algorithms.lists;

import com.wrox.algorithms.iteration.Iterator;

import com.wrox.algorithms.iteration.IteratorOutOfBoundsException;

public class GenericListIterator implements Iterator { private final List _list;

private int _current;

public GenericListIterator(List list) {

assert list != null : “list can’t be null”; _list = list;

}

public void first() { _current = 0;

}

public void last() {

_current = _list.size() - 1;

}

public boolean isDone() {

return _current < 0 || _current >= _list.size();

}

public void next() { ++_current;

}

public void previous() { --_current;

}

public Object current() throws IteratorOutOfBoundsException { if (isDone()) {

throw new IteratorOutOfBoundsException();

}

return _list.get(_current);

}

}

501

Appendix D

Exercise 5 Solution

private Element getElement(int index) { if (index < _size / 2) {

return getElementForwards(index); } else {

return getElementBackwards(index);

}

}

private Element getElementForwards(int index) { Element element = _headAndTail.getNext();

for (int i = index; i > 0; --i) { element = element.getNext();

}

return element;

}

private Element getElementBackwards(int index) { Element element = _headAndTail;

for (int i = _size - index; i > 0; --i) { element = element.getPrevious();

}

return element;

}

Exercise 6 Solution

public int indexOf(Object value) {

assert value != null : “value can’t be null”;

int index = 0;

Iterator i = iterator();

for (i.first(); !i.isDone(); i.next()) { if (value.equals(i.current())) {

return index;

}

++index;

}

return -1;

}

Exercise 7 Solution

package com.wrox.algorithms.lists;

import com.wrox.algorithms.iteration.EmptyIterator;

import com.wrox.algorithms.iteration.Iterator;

public final class EmptyList implements List {

502

Answers to Exercises

public static final EmptyList INSTANCE = new EmptyList();

private EmptyList() {

}

public void insert(int index, Object value) throws IndexOutOfBoundsException {

throw new UnsupportedOperationException();

}

public void add(Object value) {

throw new UnsupportedOperationException();

}

public Object delete(int index) throws IndexOutOfBoundsException { throw new UnsupportedOperationException();

}

public boolean delete(Object value) {

throw new UnsupportedOperationException();

}

public void clear() {

}

public Object set(int index, Object value) throws IndexOutOfBoundsException {

throw new UnsupportedOperationException();

}

public Object get(int index) throws IndexOutOfBoundsException { throw new UnsupportedOperationException();

}

public int indexOf(Object value) { return -1;

}

public boolean contains(Object value) { return false;

}

public int size() { return 0;

}

public boolean isEmpty() { return true;

}

public Iterator iterator() { return EmptyIterator.INSTANCE;

}

}

503