interface Comparable {
boolean equals(Object x);
boolean less(Object x);
}
interface Set {
boolean contains(A x);
Set include(A x);
}
abstract class Tree
implements Set {
public abstract boolean contains(A x);
public abstract Tree insert (A x);
public Set include(A x) {
return insert(x);
}
}
class EmptyTree extends Tree {
public boolean contains(A x) {
return false;
}
public Tree insert(A x) {
return new Branch(x, this, this);
}
}
class Branch extends Tree {
A elem;
Tree left;
Tree right;
public Branch(A elem, Tree left, Tree right) {
this.elem = elem;
this.left = left;
this.right = right;
}
public boolean contains(A x) {
if (x.less(elem))
return left.contains(x);
else if (elem.less(x))
return right.contains(x);
else // we assume total ordering, therefore x.equals(elem)
return true;
}
public Tree insert(A x) {
if (x.less(elem))
return new Branch(elem, left.insert(x), right);
else if (elem.less(x))
return new Branch(elem, left, right.insert(x));
else // we assume total ordering, therefore x.equals(elem)
return this;
}
}
class ComparableString implements Comparable {
private String s;
ComparableString(String s) {
this.s = s;
}
public boolean less(Object other) {
if (other instanceof ComparableString)
return s.compareTo(((ComparableString)other).s) < 0;
else
throw new Error("can't compare to non-strings");
}
}
public class TestForDuplicates {
public static void main(String[] args) {
Set set = new EmptyTree();
for (int i = 1; i < args.length; i++)
set.include(new ComparableString(args[i]));
System.out.println(
set.contains(new ComparableString(args[0])));
}
}