// NOTA: per i metodi della classe e' possibile utilizzare solo strutture dati locali
//       di appoggio di tipo StackArray 
public class Esercizio2 {

    // pre: S non nullo
    // post: ritorna una stringa che contiene tutti gli elementi in S 
    //       separati da uno spazio. L'ordine degli elementi nella stringa
    //       deve essere corrispondere all'ordinamento LIFO dello stack.
    //       Il metodo non deve alterare lo stato originale di Q
    public static String toString(StackArray S) {
	StackArray S1 = new StackArray();
	String s = "";
	Object ob;

	int i = S.size();
	while (!S.isEmpty()) {
	    ob = S.pop();
	    s = s + ob.toString() + " ";
	    S1.push(ob);
	}

	// ripristino lo stato iniziale di S
	while (!S1.isEmpty()) 
	    S.push(S1.pop());

	return s;
    }


    // pre: S non nullo 
    // post: scambia l'ordine dei primi due elementi nello stack, lasciando inalterati 
    //       gli altri elementi. Se S ha meno di due elementi allora rimane inalterato
    public static void scambia(StackArray S) {

	if (S.size() < 2)
	    return ;

	Object ob1 = S.pop();
	Object ob2 = S.pop();
	S.push(ob1);
	S.push(ob2);
    }

    // pre: S non nullo
    // post: ritorna una coda che rappresenta fedelmente lo stato attuale di S, 
    //       lasciando inalterato lo stato di S stesso    
    // NOTA: rappresenta fedelmente significa che, dopo l'esecuzione del metodo, 
    //       l'ordine di uscita degli elementi dalla coda e da S deve essere lo stesso.
    // OSS: per questo metodo e' possibile utilizzare una coda di supporto.
    public static QueueArray toQueue(StackArray S) {
	QueueArray Qout = new QueueArray();
	StackArray S1 = new StackArray();
	Object ob;

	int N = S.size();
        int i = 0;
	while (i< N) {
	    ob = S.pop();
	    Qout.enqueue(ob);
	    S1.push(ob);
	    i++;
	}

	// ripristino lo stato iniziale di S
	i = 0;
	while(i < N) {
	    S.push(S1.pop());
	    i++;
	}
	return Qout;
    }

}
