Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 27
  1. #1

    Stack implementata con linkedList

    Salve ragazzi, sto impazzendo da giorni e giorni con un esercizio ma non riesco a venirne a capo.
    Ecco il testo:
    codice:
    Si fornisca un'efficiente implementazione dell'interfaccia StackSet140910<E>, come mostrata nella pagina successiva. La classe rappresenta un insieme ordinato i cui elementi sono semplici stack (classe MStack<E>). Ogni stack dell'insieme è rappresentato dal suo elemento che si trova in cima allo stack. Ogni stack potrà contenere al massimo 50 elementi. L'insieme dovrà essere rappresentato attraverso una lista concatenata e gli stack dell'insieme dovranno essere ordinati in base al loro elemento rappresentante. Uno stack che non contiene alcun elemento dovrà apparire nella lista prima di qualsiasi altro stack (considerarlo come l'elemento più piccolo dell'insieme) La gestione delle eccezioni all'interno delle classi è facoltativa. Realizzare in seguito, mediante il metodo main() della classe, un programma Java che prenda in input un file di testo contenente una sequenza di numeri interi e restituisca in output un file di testo contenente le specifiche della struttura ottenuta dopo l'inserimento di tali numeri a partire da uno StackSet140910 contenente 3 stack vuoti. 
     Il file di input contiene una sequenza di numeri interi, uno per riga.
    File di output Il file di output dovrà contenere la lista degli elementi contenuti nei tre stack dell'insieme (uno stack per riga), iniziando dagli elementi che si trovano in cima alla struttura. 
    
    Interfaccia StackSet140910 import java.util.*; 
    public interface StackSet140910<E> extends Iterable<E>
    { 
    public int stacks (); // ritorna il numero di stack (di tipo MStack<E>) dell'insieme 
    public int items (); // ritorna il numero di elementi (E) dell'insieme 
    public MStack<E> getMin (); /** ritorna il primo stack vuoto dell'insieme. Se non esistono stack vuoti nell'insieme ritorna lo stack con il più piccolo valore in testa */
    public E pop (); // effettua il pop sul primo stack dell'insieme 
    public void push (E elem); // effettua il push di un elemento sul primo stack dell'insieme 
    public void addStack (); // aggiunge un nuovo stack vuoto all'insieme
     public Iterator<E> iterator(); // ritorna un iteratore di tutti gli elementi (di tipo E) // contenuti negli stack dell'insieme }

    Ecco invece il mio codice:
    codice:
    import java.io.*;
    import java.util.*;
    
    public class LinkedList<E extends Comparable>
    {
        protected NodoL<E> header, trailer;
        private int size;
        
        public LinkedList()
        {
            header=new NodoL<E>(null,null,null);
            trailer=new NodoL<E>(null,header,null);
            size=0;
        }
        
        public int size()
        {
            return size;
        }
    
        public boolean isEmpty()
        {
            return (size==0);
        }
        
        //ritorna il primo elemento
        public NodoL<E> first()
        {
            if(isEmpty())
                return null;
            else
                return header.getNext();
        }
        
        //ritorna l'ultimo elemento
        public NodoL<E> last()
        {
            if(isEmpty())
                return null;
            else
                return trailer.getPrev();
        }
        
        //aggiungo all'inizio
        public void addFirst(E element)
        {
            NodoL<E> newNodo=new NodoL<E>(element,header,header.getNext());
            header.getNext().setPrev(newNodo);//quello che era il successore di header, adesso avrà come predecessore il nuovo nodo
            header.setNext(newNodo);//imposto il successore di header
            size++;
        }
        
        //aggiungo alla fine 
        public void addLast(E element)
        {
            NodoL<E>newNodo= new NodoL<E>(element,trailer.getPrev(),trailer);
            trailer.getPrev().setPrev(newNodo);//quello che era il predecessore di trailer, adesso è il predecessore del nuovo nodo
            trailer.setPrev(newNodo);//imposto il nuovo predecessore di trailer
            size++;
        }
        
        //se aggiungo in un qualsiasi punto
        public void add(NodoL<E> node, E element)
        {
            NodoL<E> newNodo=new NodoL<E>(element,node.getPrev(),node.getNext());
            node.getPrev().setNext(newNodo);//il predecessore del vecchio nodo, avrà come successore il nuovo nodo
            node.setPrev(newNodo);
            size++;
        }
        
        //trovo il minimo
        public E minimo()
        {
            NodoL<E>aux=header.getNext();
            NodoL<E>min=aux;
            while(aux!=null)
            {
                if(aux.getElement().compareTo(min.getElement())<0)
                    aux=min;
                aux=aux.getNext();
            }
            return min.getElement();
        }
            
        //cancello un nodo
        public void remove(NodoL<E> node)
        {
            NodoL<E> prev=node.getPrev();
            NodoL<E>next=node.getNext();
            prev.setNext(next);
            next.setPrev(prev);
            node.setPrev(null);
            node.setNext(null);
            size--;
        }
        
        public String toString()
        {
            String str="";
            NodoL<E>aux=first();
            while(aux!=trailer)
            {
                str+=aux.getElement()+" ";
                aux=aux.getNext();
            }
            return str;
        }
    }
    
    
    class NodoL<E>
    {
        private E element;
        private NodoL<E>prev;
        private NodoL<E> next;
        
        public NodoL(E element, NodoL<E> prev, NodoL<E> next)
        {
            this.element=element;
            this.next=next;
            this.prev=prev;
        }
        
        public E getElement()
        {
            return element;
        }
        
        public void setElement(E element)
        {
            this.element=element;
        }
        
        public NodoL<E> getPrev()
        {
            return prev;
        }
        
        public void setPrev(NodoL<E> prev)
        {
            this.prev=prev;
        }
        
        public NodoL<E> getNext()
        {
            return next;
        }
        
        public void setNext(NodoL<E> next)
        {
            this.next=next;
        }
    }

    codice:
    import java.io.*;
    import java.util.*;
    
    public class MStack<E>
    {
    	protected int capacità;//effettiva capacità dell'array
    	public static final int maxCapacità=50;//numero massimo di elementi che può contenere
    	private E[]set;//array per implementare lo stack
    	private int top;//indice dell'elemento in cima allo stack
    	
    	public MStack()
    	{
    		this(maxCapacità);//capacità di default
    	}
    	
    	public MStack(int cap)
    	{
    		capacità=cap;
    		set=(E[]) new Object[capacità];
    		top=0;
    	}
    	
    	public boolean isEmpty()
    	 {
    		 return(top==0);
    	 }
    	 
    	 public int size()
    	 {
    		 return(top+1);
    	 }
    	 
    	//cancello dalla cima
    	public E pop() throws EmptyStackException
    	{
    		if(isEmpty())
    			throw new EmptyStackException("stack vuoto");
    		else
    		return set[--top];
    	}
    	
    	//aggiungo in cime
    	public void push(E element) throws FullStackException
    	{
    		if(size()==capacità)
    			throw new FullStackException("stack pieno");
    		else
    		set[top++]=element;
    	}
    	
    	public E getTop() throws EmptyStackException
    	{
    		if(isEmpty())
    			throw new EmptyStackException("stack vuoto");
    		else
    		return set[top];
    	}
    }
    codice:
    import java.io.*;
    import java.util.*;
    
    public class mioStack<E extends Comparable> implements StackSet140910<E>
    {
    	private int stacks;
    	private int items;
    	LinkedList<E> lista;
    	
    
    	public mioStack()
    	{
    		stacks=0;
    		items=0;
    		lista=new LinkedList<E>();
    	}
    	
    	//ritorna il numero di elementi(di tipo MStack<E>) dell'insieme
    	public int stacks()
    	{
    		return stacks;
    	}
    	
    	//ritorna il numero di elementi di tipo E dell'insieme
    	public int items()
    	{
    		return items;
    	}
    	
    	//ritorna il primo stack vuoto dell'insieme.se non esistono stack vuoti nell'insieme
    	//ritorna lo stack con il più piccolo valore in testa
    	public MStack<E> getMin()
    	{
    		MStack<E> ms=(MStack<E>)lista.first();//QUI MI DA ERRORE
    		if(ms.isEmpty())//se è vuoto...
    			return ms;//lo restituisce...altrimenti faccio un confronto per trovare il minore
    		else
    			return lista.minimo();//QUI MI DA UN ALTRO ERRORE
    		
    		
    	}
    	
    	//effettua il pop sul primo stack dell'insieme
    	public E pop()
    	{
    		E element=lista.first();//QUI MI DA ERRORE
    		lista.remove(element);
    		stacks--;
    		return element;
    		
    	}
    	public void push(E element)
    	{
    		lista.addFirst(element);
    		items++;
    	}
    			
    }
    Come devo sistemare questi metodi?non capisco proprio :-(

  2. #2
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Già che ci sono ne approfitto per darti qualche indicazione...
    1) LinkedList è una classe della libreria java.util. Può convivere benissimo cone la classe LinkedList che hai sviluppato tu, ma forse sarebbe meglio - per motivi di chiarezza - se a quest'ultima assegnassi un nome diverso;

    2) Nel costruttore di LinkedList imposti il prev di "trailer" con "header"... ma non imposti mai il next di "header" a "trailer" (come secondo me dovreti fare). Magari è quello che vuoi, ma poi questa condizione particolare non viene ripristinata correttamente, ad esempio, nel remove();

    3) Sempre in LinkedList c'è un errore nel metodo addLast(). Ti riporto la versione corretta:

    codice:
    //aggiungo alla fine
    public void addLast(E element)
    {
      NodoL<E>newNodo= new NodoL<E>(element,trailer.getPrev(),trailer);
      trailer.getPrev().setNext(newNodo);//quello che era il predecessore di trailer, adesso è il predecessore del nuovo nodo
      trailer.setPrev(newNodo);//imposto il nuovo predecessore di trailer
      size++;
    }
    Se noti, l'errore è nella seconda istruzione del metodo (e in proposito dovresti anche sistemare il commento associato);

    4) Sempre in LinkedList potrebbe essere opportuno avere due metodi addBefore() e addAfter() invece di un solo metodo add() (che comunque fai agire come un addBefore()). Anche qui però c'è un errore:

    codice:
    //se aggiungo in un qualsiasi punto
    public void add(NodoL<E> node, E element)
    {
      NodoL<E> newNodo=new NodoL<E>(element,node.getPrev(),node);
      node.getPrev().setNext(newNodo);//il predecessore del vecchio nodo, avrà come successore il nuovo nodo
      node.setPrev(newNodo);
      size++;
    }
    Il problema era nella prima istruzione del metodo: il successore del parametro "node" non viene mai coinvolto nell'operazione;

    5) Legato alla questione 2: se segui il suggerimento che ti ho dato, la condizione di uscita dal while nel metodo minimo() dovrebbe essere

    codice:
    while(aux!=trailer)
    Come condizione preliminare, inolte, io ci metterei un

    codice:
    if (isEmpty())
    {
      return null;
    }
    Ti segnalo anche qua un errore. All'interno del ciclo while l'istruzione corretta è

    codice:
    min = aux;
    non viceversa. Occhio!

    6) In toString() di LinkedList l'inizializzazione di aux va fatta come nel metodo minimo, e cioè

    codice:
    NodoL<E>aux=header.getNext();
    Questo perchè se la lista fosse vuota il metodo first() ti ritornerebbe "null", con conseguente NullPointerException alla prima iterazione del ciclo;

    7) Nonostante sia ammesso, è sempre meglio non usare identificatori con caratteri particolari, in quanto potrebbero creare dei problemi al compilatore. Nella classe MStack usi "capacità" e "maxCapacità", ma sarebbe preferibile sostituire la "a" accentata finale con una "a" semplice.

  3. #3
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Gli errori che riscontri sono causati da una errata gestione dei generics. E' abbastanza complicato spiegare a parole perchè, ma ci provo.

    Il problema è che all'interno della classe "mioStack" (importante: nel seguito parlerò solo ed esclusivamente della struttura di questa classe) usi la classe generica "E" in due contesti diversi:
    - come elementi della lista di mioStack
    - come elementi della lista di MStack

    Ma non sono elementi dello stesso tipo!
    Se dentro "MStack" andrai a mettere (per esempio) delle String, conseguentemente mioStack sarà composta da elementi del tipo MStack<String>: sono diverse e per questo motivo non puoi usare la classe generica "E" per rappresentare entrambe le cose.

    Per come ti è stato richiesto di implementare la classe (sto guardando l'interfaccia che ti è satta fornita insieme alla traccia) tu non devi usare la classe generica "E" per indicare gli elementi da inserire in "mioStack": ti è espressamente richiesto che essi siano di tipo MStack. Quello che dovrà essere "catturato" sono gli elementi ammessi all'interno di MStack.

    In questi termini, la tua classe dovrebbe essere modificata in:

    codice:
    import java.io.*;
    import java.util.*;
    
    public class mioStack<E extends Comparable> implements StackSet140910<E>
    {
    	private int stacks;
    	private int items;
    	LinkedList<MStack<E>> lista;
    
    
    	public mioStack()
    	{
    		stacks=0;
    		items=0;
    		lista=new LinkedList<<MStack<E>>();
    	}
    
    	//ritorna il numero di elementi(di tipo MStack<E> ) dell'insieme
    	public int stacks()
    	{
    		return stacks;
    	}
    
    	//ritorna il numero di elementi di tipo E dell'insieme
    	public int items()
    	{
    		return items;
    	}
    
    	//ritorna il primo stack vuoto dell'insieme.se non esistono stack vuoti nell'insieme
    	//ritorna lo stack con il più piccolo valore in testa
    	public MStack<E> getMin()
    	{
    		MStack<E> ms=lista.first();//QUI MI DA ERRORE
    		if(ms.isEmpty())//se è vuoto...
    			return ms;//lo restituisce...altrimenti faccio un confronto per trovare il minore
    		else
    			return ms.minimo();//QUI MI DA UN ALTRO ERRORE
    
    
    	}
    
    	//effettua il pop sul primo stack dell'insieme
    	public MStack<E> pop()
    	{
    		MStack<E> element=lista.first();//QUI MI DA ERRORE
    		lista.remove(element);
    		stacks--;
    		items -= element.size();
    		return element;
    
    	}
    	public void push(MStack<E> element)
    	{
    		lista.addFirst(element);
    		stacks++;
    		items += element.size();
    	}
    
    }
    Prova a compilarla e a vedere se funziona (ho solo modificato il sorgente, potrebbe essermi sfuggito qualcosa). Nei metodi push() e pop() ho anche aggiunto le istruzioni che gestiscono correttamente la modifica dell'attributo "item".

  4. #4
    Grazie mille...sei stato davvero gentilissimo/a Capito alla perfezione dove sbagliavo.
    Ho però tre domande da farti:
    1) nella classe LinkedList, metodo add() nella prima istruzione del metodoerchè il successore del parametro "node" non viene mai coinvolto nell'operazione?
    2)Tu mi dici di aggiungere addBefore e addAfter...ma non sono i miei addFirst() e addLast()?
    3)nell'interfaccia da implementare ho: public E pop() e non come l'hai modificata tu. stessa cosa per public void push(E elem)...infatti avevo difficoltà qui.

    Pre il resto, grazie mille, mi sei stato/a di grandissimo aiuto.

  5. #5
    Compilandolo mi dà i seguenti errori:

    codice:
    mioStack.java:8: type parameter MStack<E> is not within its bound
    	LinkedList<MStack<E>> lista;
    	                 ^
    mioStack.java:34: incompatible types
    found   : NodoL<MStack<E>>
    required: MStack<E>
    		MStack<E> ms=lista.first();
    		                        ^
    mioStack.java:38: cannot find symbol
    symbol  : method minimo()
    location: class MStack<E>
    			return ms.minimo();
    			         ^
    mioStack.java:62: incompatible types
    found   : NodoL<MStack<E>>
    required: MStack<E>
    		MStack<E> element=lista.first();
    		                             ^
    mioStack.java:63: remove(NodoL<MStack<E>>) in LinkedList<MStack<E>> cannot be applied to (MStack<E>)
    		lista.remove(element);

  6. #6
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Lieto (con la "o" finale, ma mi rendo conto che il mio nickname - che per la cronaca sono le prime 4 lettere del mio cognome - possa trarre in inganno ) di esserti stato utile, soprattutto se alla fine i miei post non sono usciti troppo incasinati.

    A proposito: volevo dirti che ti ho fatto un sacco di puntualizzazioni, ma dal codice che ho visto mi sembra che tu abbia una buona padronanza del linguaggio e della programmazione ad oggetti. Poi, un po' sono pignolo io e un po' è più facile per un'altra persona trovare eventuali errori nel tuo listato, ma volevo che fosse chiaro - se necessario - che non è che "hai sbagliato tutto", anzi!

    In merito alle tue domande:

    1) Ipotizziamo che tu abbia una LinkedList fatta così:

    codice:
    H <-> 1 <-> 2 <-> 3 <-> T
    Naturalmente H sta per header, T sta per trailer e lo sgorbio fra i nodi vuole essere una doppia freccia (doppia in quanto utilizzando sia "prev" che "next" hai una concatenazione bidirezionale).
    Ora, diciamo che vuoi inserire un nuovo nodo "N" tra il nodo 1 e il nodo 2 con il metodo add(). La chiamata che farai è:

    codice:
    lista.add(2, nuovo_elemento);
    e, al termine dell'esecuzione del metodo, vorrai che la lista assuma questa struttura:

    codice:
    H <-> 1 <-> N <-> 2 <-> 3 <-> T
    In pratica, il nodo "N" avrà come prev il nodo 1 e come next il nodo 2, che è quello passato come parametro.

    Andiamo a vedere cosa succede nella versione originale del metodo add(), quella con l'istruzione "incriminata":

    codice:
    NodoL<E> newNodo=new NodoL<E>(element,node.getPrev(),node.getNext());
    Viene creato un nuovo nodo "newNodo" in cui vengono impostati l'elemento contenuto, il suo prev e il suo next. In particolare:
    - prev viene impostato con il prev del nodo parametro, e quindi il nodo 1
    - next viene impostato con il next del nodo parametro, e quindi il nodo 3
    Ma questo è sbagliato: abbiamo detto poche righe fa, guardando lo schema, che il next del nuovo nodo dovrà essere il 2, ossia il parametro stesso. Per questo motivo, l'istruzione corretta è:

    codice:
    NodoL<E> newNodo=new NodoL<E>(element,node.getPrev(),node);
    Se ci pensi assomiglia un po' all'indovinello: "se in una gara sorpasso chi è in terza posizione, in che posizione mi vengo a trovare?". Istintivamente viene da rispondere "secondo", ma la risposta esatta è che se sorpasso il terzo a quel punto il terzo divento io .

    2) addFirst() e addLast() aggiungono rispettivamente in testa e in coda alla lista.
    Con addBefore() e addAfter() io intendo due metodi che ricevono in ingresso un nodo e un elemento (proprio come il metodo add() di cui abbiamo appena discusso) e che aggiungono tale elemento - rispettivamente - prima e dopo il nodo passato come parametro. Il metodo add(), così come l'hai definito, si comporta esattamente come quello che io ho chiamato "addBefore()".

    3) In effetti, non avevo fatto caso che la tua interfaccia fosse definita così. Facciamo così: poichè in questo momento non ho un ambiente di sviluppo utilizzabile - quindi ho qualche difficoltà anche solo a editare il codice - ci do un'occhiata domani mattina, ok? Sia ai due metodi push() e pop() sia agli errori di compilazione che ricevi.

  7. #7
    Grazie mille per la spiegazione...sei stato chiarissimo davvero. A poco a poco i miei ultimi dubbi stanno scomparendo...spero
    Ho sistameto i metodi add()...sono corretti allora così?
    codice:
    //aggiungo prima di un determinato nodo
    	public void addBefore(NodoL<E> node, E element)
    	{
    		NodoL<E> newNodo=new NodoL<E>(element,node.getPrev(),node);//il successore del parametro node non viene mai coinvolto nell'operazione
    		node.getPrev().setNext(newNodo);//il predecessore del vecchio nodo, avrà come successore il nuovo nodo
    		node.setPrev(newNodo);
    		size++;
    	}
    	
    	//aggiungo dopo un determinato nodo
    	public void addAfter(NodoL <E> node,E element)
    	{
    		NodoL<E> newNodo=new NodoL<E>(element,node,node.getNext());
    		node.getNext().setPrev(newNodo);//il successore del vecchio nodo,, ha come predecessore il nuovo nodo
    		node.setNext(newNodo);
    		size++;
    	}
    Aspetto allora tue notizie, in mattinata per le altre cose.Mille grazie ancora.

    proposito: volevo dirti che ti ho fatto un sacco di puntualizzazioni, ma dal codice che ho visto mi sembra che tu abbia una buona padronanza del linguaggio e della programmazione ad oggetti. Poi, un po' sono pignolo io e un po' è più facile per un'altra persona trovare eventuali errori nel tuo listato, ma volevo che fosse chiaro - se necessario - che non è che "hai sbagliato tutto", anzi!
    Grazie è 4 anni che programmo con gli oggetti, mi mancano due materie per la laurea in informatica ma mi sono bloccata con questa materia e non riesco ad andare avanti

  8. #8
    credo di aver sistemato anche il pop...che ne dici?Però mi dà errore:
    incompatible types
    found : NodoL<MStack<E>>
    required: MStack<E>
    MStack<E> ms=lista.first();

    codice:
    public E pop()
    	{
    		NodoL<E> element=lista.first();
    		lista.remove(element);
    		stacks--;
    		items-=element.size();
    		return element.getElement();
    		
    	}
    Ho dovuto aggiungere però il metodo size() nella classe NodeL...sennò non lo riconosceva

  9. #9
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Ok, ho riguardato il tutto con calma (scusa il ritardo, ma sono in ufficio e a volte mi tocca lavorare ) e ho capito dov'è l'errore.
    Il punto è che la tua classe LinkedList per come è definita ammette solo classi generiche che implementano l'interfaccia Comparable:

    codice:
    public class LinkedList<E extends Comparable>
    Se all'interno della classe mioStack la vogliamo utilizzare è necessario rispettare questa dichiarazione. Ossia, per fare

    codice:
    LinkedList<MStack<E>> lista;
    bisogna che quello che sta fra le parentesi angolari "<" e ">" (e cioè "MStack<E>") implementi l'interfaccia Comparable. Ma la dichiarazione della classe MStack è

    codice:
    public class MStack<E>
    NON viene implementata Comparable e quindi il compilatore ti segnala che nella classe mioStack non puoi utilizzare una LinkedList definita come sopra.

    La questione che vorrei definire però è relativa alla traccia del problema. L'ho riletta con calma (insieme alle specifiche dell'interfaccia che ti è stata fornita) e non riesco a capire: cosa ci va dentro la lista? Gli MStack o i singoli elementi?

  10. #10
    Da come ho capito io il testo, nella lista ci vanno i singoli elementi che rappresentano lo stack...perchè dice che gli stack dell'insieme dovranno essere ordinati in base al loro elemento rappresentante.
    sempre nel testo il Prof dà come input
    5
    3
    6
    8
    1
    2
    4
    7

    e come output:
    6
    7 4 2 1 5
    8 3

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.