//------------
// Da Introduction to Programming Using Java: An Object-Oriented Approach
//	Arnow/Weiss: capitolo 8
//------------
//Implementazione con le strutture collegate lineari

import java.io.*;
import java.util.*;

class Set {
    public Set() {
	nodoinit = null;
    }
    
    public boolean isEmpty() {
	return nodoinit==null;
    }
    
    public int size() {
	int cont = 0;
	Nodo aux = nodoinit;
	while(aux!=null) {
	    cont++;
	    aux = aux.getNext();
	}
	return cont;
    }
    
    public boolean contains(Object o) {
	Nodo aux = nodoinit;
	while (aux!=null) {
	    Object elem = aux.getInfo();
	    if (elem.equals(o))
		return true;
	    aux = aux.getNext();
	}
	return false;
    }
    
    public void addElement(Object o) {
	if (!contains(o)) {
	    Nodo aux = new Nodo();
	    aux.setInfo(o);
	    aux.setNext(nodoinit);
	    nodoinit = aux;
	}
    }

    public void removeElement(Object o) {
	if (nodoinit==null) return;
	else if (nodoinit.getInfo().equals(o)) {
	    nodoinit = nodoinit.getNext();
	    return;
	}
	else {
	    Nodo aux = nodoinit;
	    while (aux.getNext()!=null) {
		if (aux.getNext().getInfo().equals(o)) {
		    aux.setNext(aux.getNext().getNext());
		    return;
		} 
		aux = aux.getNext();
	    }
	}
    }
    
    public Set copy() {
	Set destSet = new Set();
	Nodo aux = nodoinit;
	while (aux!=null) {
	    destSet.addElement(aux.getInfo());
	    aux = aux.getNext();
	}
	return destSet;
    }
    
    public Set union(Set s) {
	Set unionSet = copy();
	Nodo aux = s.nodoinit;
	while (aux!=null) {
	    unionSet.addElement(aux.getInfo());
	    aux = aux.getNext();
	}
	return unionSet;
    }
    
    public Set intersection(Set s) {
	Set interSet = new Set();
	Nodo aux = nodoinit;
	while (aux!=null) {
	    Object elem = aux.getInfo();
	    if (s.contains(elem))
		interSet.addElement(elem);
	    aux = aux.getNext();
	}
	return interSet;
    }
    
    public Set difference(Set s) {
	Set diffSet = copy();
	Nodo aux = s.nodoinit;
	while (aux!=null) {
	    diffSet.removeElement(aux.getInfo());
	    aux = aux.getNext();
	}
	return diffSet;
    }

    public Enumeration elements() {
	return new EnumerationSCL(nodoinit);
    }
    
    public String toString() {
	String res = "";
	Nodo aux = nodoinit;
	while (aux!=null) {
	    res = res + aux.getInfo().toString() + " ";
	    aux = aux.getNext();
	}
	return res;
    }
    
    public boolean equals(Object o) {
	Set s = (Set)o;

	Enumeration e = s.elements();
	while (e.hasMoreElements()) 
	    if (!this.contains(e.nextElement())) return false;

	e = this.elements();
	while (e.hasMoreElements())
	    if (!s.contains(e.nextElement())) return false;
	
	return true;
    }

    Nodo nodoinit;
}
