Implementare Iteratore per Lista Concatenata

di il
9 risposte

Implementare Iteratore per Lista Concatenata

Salve,
ho realizzato una lista concatenata con relativa classe iteratore ma non ho idea su come devo implementare l'iteratore per farlo funzionare.

La lista concatenata è:

package com_antomau_ListeConcatenate.LinkedList;

import com_antomau_ListeConcatenate.Studente.Studente;

import java.util.NoSuchElementException;

import com_antomau_ListeConcatenate.ListIterator.ListIterator;


public class ListaConcatenata {
	
	
	
	//viene dichiarato quello che sarà un nodo della lista - esso contiene un oggetto di tipo studente e un collegamento al nodo successivo
	public class Node
	{
		//variaibli contenute in ogni nodo della lista
		Studente student;
		public Node link; //collegamento al nodo successivo
	} //end of Node class


	//variabili
	private Node headList; //nodo testa della lista


	/**
	 * Metodo costruttore della classe: esso inizializza il nodo in testa alla lista
	 */
	public ListaConcatenata()
	{
		headList = null; //il nodo in testa alla lista viene inizializzato a null perché all'inizio dell'esecuzione del programma la lista è vuota
	}
	
	
	/**
	 * Questo metodo restituisce il nodo in testa alla lista
	 * @return Lo studente che si trova in testa alla lista, altrimenti null se la lista è vuota
	 */
	public Studente getFirst()
	{
		if (!(headList == null)) //if (headlist!=null)
		{
			return headList.student;
		} //end of if
		//throw NoSucheElementException();
		return null;
	} //end of firstToString method
	
	
	public void removeFirst()
	{
		if (!(headList!=null)) //if (headList==null)
			return;
		else 
		{
			headList = headList.link;
		} //end of else
	} //end of removeFirst
	
	
	/**
	 * Questo metodo aggiunge un nodo in testa alla lista
	 * @param s Lo studente da aggiungere come oggetto del nodo della lista
	 */
	public void addFirst(Studente s)
	{
		System.out.println("debug current data = " + s.getSurname() + " " + s.getName() + " " + s.getSerial() + " " + s.getExamName() + " " + s.getExamVote()); //debug
		Node newNode = new Node();
		
		newNode.student = s;
		
		newNode.link = headList;
		
		headList = newNode;
	} //end of addFirst
	
	
	
	
	public void addLast(Studente s)
	{
		if (headList==null) addFirst(s);
		else {
			Node newNode = new Node();
			newNode.student = s;
			newNode.link = null;
			Node current = headList;
			Node previous = null;
			while (current.link!=null)
			{
				previous = current;
				current = current.link;
			} //end of while
			current.link = newNode;
		} //end of else
	} //end of addLast
	
	
	
	
	
	
	
	
	
	//iteratore per la lista concatenata
	/*
	 * Questo iteratore viene creato appositamente per la lista realizzata in questo programma
	 * pertanto i suoi metodi restituiranno studenti
	 * e coterranno riferimenti alle caratteristiche della lista attuale
	 * e/o dati pertinenti alla lista in questione
	 */
	public class LinkedListIterator implements ListIterator
	{
		//variabili
		Node current; //riferimento al nodo corrente referenziato dall'iteratore
		Node previous; //riferimento al nodo precedente a quello referenziato dall'iteratore
		//
		/**
		 * Questo è il costruttore della classe
		 */
		public LinkedListIterator()
		{
			current = null; //essendo un passaggio eseguito all'inizio dell'esecuzione del codice la lista e' vuota e pertanto il riferimento al nodo attuale e' null
			previous = null; //per il medesimo motivo della linea precedente si inizializza questa variabile a null
		} //end of builder
		//
		/**
		 * Questo metodo sposta l'iteratore nella posizione successiva della lista
		 */
		@Override
		public Studente next()
		{
			previous = current; //il riferimento al nodo precedente assume il valore del nodo attuale
			if (!hasNext()) throw new NoSuchElementException();
			//
			//l'obbiettivo e' scorrere la lista mediante un iteratore
			if (!(current!=null)) //if (current == null)
				current = headList; //se current e' uguale a null vuol dire che non referenzia nulla e quindi andra' a referenziare il nodo in testa alla lista
			else current = current.link; // altrimenti il riferimento al nodo attuale diviene il nodo successivo a quello attuale
			/*
		 	 * il metodo deve restituire quello che è divenuto l'elemento attuale
			 */
			return current.student;
		} //end of next
		//
		/**
		 * Questo metodo verifica che esista un nodo successivo a quello attuale
		 * @return Vero se esiste un nodo successivo a quello attualmente referenziato, falso se questo non esiste.
		 */
		@Override
		public boolean hasNext()
		{
			if (!(current!=null)) //if (current==null) //se il nodo corrente è nullo
				return headList!=null; //restituisce il risultato dell'espressione (headList!=null): è vero se headList esiste, è falso se headList non esiste
			else return current.link!=null; //se il nodo corente non è nullo - restituisce il riultato dell'espressione (current.link!=null): è vero se il nodo successivo a quello attuale esiste, è falso se il nodo successivo a quello attuale non esiste
		} //end of hasNext
		//
		/**
		 * Questo metodo aggiunge un elemento alla lista.
		 * @param s Lo studente da aggiungere alla lista.
		 */
		@Override
		public void add(Studente s)
		{
			if (!(current!=null)) { //if (current==null) //se il nodo current e' null vuol dire che la lista e' vuota
				addFirst(s); //lo studente (oggetto) da aggiungere viene aggiuntom in testa alla lista chiamando il metodo addFirst
				current = headList; //il riferimento al nodo corrente diviene il nodo in testa alla lista
			} else {
				Node newNode = new Node(); //viene creato un nuovo nodo
				newNode.student = s; //l'oggetto (studente) del nodo divene s
				newNode.link = current.link; //il nodo successivo a quello da aggiungere sara' il nodo successivo a quello attualmente referenziato
				current = newNode; //il nodo attualmente referenziato diviene il nodo appena aggiunto
			} //end of else
			previous = current; //i riferimento al nodo precedente diviene il riferimento al nodo corrente per bloccare alcune operazioni in seguito descritte
		} //end of add
		//
		/**
		 * Questo metodo rimuove un nodo della lista
		 */
		@Override
		public void remove()
		{
			/*
			 * Come noi sappiamo da una lista non si puo' eliminare un nodo senza prima averlo referenziato
			 * oppure immediatamente dopo averne inserito uno
			 * oppure immediatamente dopo averne eliminato uno
			 * pertanto per fare si che cio' ia realizzabile in maniera corretta
			 * alla fine di ogni metodo che non puo' precedere l'eliminazione il riferimento al nodo precedente viene modificato al fine di referenziare il nodo attuale
			 * cosi', giunti a questo punto del programma, viene verificato il valore del riferimento al nodo precedente
			 * e se questo risulta essere uguale al nodo attuale viene lanciata un eccezione
			 */
			if (previous == current) throw new IllegalStateException();
			else if (current == headList) removeFirst(); //se il nodo corrente fa riferimento al nodo in testa alla lista viene chiamato il metodo per l'eliminazione del nodo in testa alla lista
			else previous.link = current.link; //altrimenti, se il nodo si trova in un altra posizione, il riferimento al nodo successivo del nodo precedente diviene il riferimento al nodo successivo al nodo attuale
			/*
			 * per impedire l'eliminazione di un nodo immediatamente dopo che ne sia gia' stato eliminato uno
			 * viene imposto che previous e current siano uguali
			 * in questo caso, essendo appena stato eliminato il nodo corrente, il nodo corrente referenziera' il nodo precedente
			 */
			current = previous;
		} //end of remove
		//
		/**
		 * Questo metodo modifica l'oggetto contenuto nel nodo attualmente referenziato
		 * @param s Lo studente da impostare come oggetto del nodo attuale
		*/
		@Override
		public void set(Studente s)
		{
			if (!(current==null)) //if (current!=null)
				current.student = s; //se current e' diverso da null il suo oggetto (student) viene modificato con quello passato al metodo
			else //altrmenti, se current e' uguale a null
				throw new NoSuchElementException(); //viene lanciata un eccezione in merito ad un oggetto inesistente
		} //end of set
	} //end of LinkedListIterator class

} //end of class
L'interfaccia per l'iteratore è:

package com_antomau_ListeConcatenate.ListIterator;
import com_antomau_ListeConcatenate.Studente.Studente;
public interface ListIterator {
	public Studente next();
	public boolean hasNext();
	public void add(Studente s);
	public void remove();
	public void set (Studente s);
} //end of interface
La classe che definisce l'oggetto studente è:

package com_antomau_ListeConcatenate.Studente;

public class Studente {
	
	//variabili
	String surname;
	String name;
	int serialNumber;
	String examName;
	int  examVote;
	
	/**
	 * Builder
	 * @param s Surname
	 * @param n Name
	 * @param se Serial Number
	 * @param ne Exam's name
	 * @param ve Exam's vote
	 */
	public Studente(String s, String n, int se, String ne, int ve)
	{
		this.surname = s;
		this.name = n;
		this.serialNumber = se;
		this.examName = ne;
		this.examVote = ve;
	}
	
	/**
	 * @return Student's surname.
	 */
	public String getSurname()
	{
		return surname;
	}
	
	/**
	 * @retur Student's name.
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * @return Student's serial number.
	 */
	public int getSerial() {
		return serialNumber;
	}
	
	/**
	 * @return Exam's name.
	 */
	public String getExamName() {
		return examName;
	}
	
	/**
	 * @return Exam's vote.
	 */
	public int getExamVote() {
		return examVote;
	}

} //end of class
Il file contenente il metodo main è:

package com_antomau_ListeConcatenate.UserInterface;

import com_antomau_ListeConcatenate.Studente.Studente;
import com_antomau_ListeConcatenate.LinkedList.ListaConcatenata;
import com_antomau_ListeConcatenate.ListIterator.*;

import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Scanner;
import java.io.*;

public class UserListeConcatenate {
	
	private static File file;
	
	private static Scanner in;
	
	private static ListaConcatenata myList;
	
	public static void main(String[] args) {
		
		JFrame f = new JFrame();
		f.setSize(300, 300);
		f.setLayout(new BorderLayout());
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel consolePanel = new JPanel();
		consolePanel.setLayout(new GridLayout(4,3));
		
		JButton exitButton = new JButton("Exit");
		JButton openDBButton = new JButton("Open database");
		JButton saveDBButton = new JButton("Save database");
		JButton addToHeadListButton = new JButton("Add data to lsit's head");
		JButton addToEndListButton = new JButton("Add data to list's end");
		JButton printListButton = new JButton("Print all data");
		JButton searchSurnameButton = new JButton("Search by surname");
		JButton searchNumberButton = new JButton("Search by serial number");
		JButton deleteSurnameButton = new JButton("Delete data by surname");
		JButton deleteNumberButton = new JButton("Delete data by serial number");
		JButton deleteHeadList = new JButton("Delete data in list's head");
		JButton deleteEndList = new JButton("Delete data in list's end");
		
		consolePanel.add(openDBButton);
		consolePanel.add(saveDBButton);
		consolePanel.add(exitButton);
		consolePanel.add(addToHeadListButton);
		consolePanel.add(addToEndListButton);
		consolePanel.add(printListButton);
		consolePanel.add(searchSurnameButton);
		consolePanel.add(searchNumberButton);
		consolePanel.add(deleteSurnameButton);
		consolePanel.add(deleteNumberButton);
		consolePanel.add(deleteHeadList);
		consolePanel.add(deleteEndList);
		
		JPanel contentPanel = new JPanel();
		
		f.add(consolePanel, BorderLayout.NORTH);
		f.add(contentPanel, BorderLayout.CENTER);
		
		
		f.pack();
		
		
		JFileChooser fileChooser = new JFileChooser(); //new fileChooser object
		
		
		
		
		
		class openDBButtonListenerClass implements ActionListener {
			@Override
			public void actionPerformed (ActionEvent e) {
				//open database and load data
				fileChooser.showOpenDialog(f); //show new file chooser windows into frame f
				try {
					file = fileChooser.getSelectedFile(); //"file" become the file given by file chooser
					in = new Scanner(file);
				} catch(Exception exc) { //se si entra nel ramo catch stampa il log dell'errore e interrompi l'esecuzione del metodo corrente
					exc.printStackTrace();
					return;
				} //end of try/catch
				
				//String cognome, nome, esame;
				//int matricola, vesame;
				
				while (in.hasNext())
				{
					/*
					cognome = in.next();
					nome = in.next();
					matricola = in.nextInt();
					esame = in.next();
					vesame = in.nextInt();
					*/
					
					Studente stud = new Studente(in.next(), in.next(), in.nextInt(), in.next(), in.nextInt()); //vengono acquisiti i dati e si fa in modo che lo scanner scorra verso la serie di token successiva (più token vengono scansionati insieme)
					
					myList.addFirst(stud);
					
					//add data to list here
					//list.add(cognome, nome, matricola, esame, vesame);
					//System.out.println("current data = " + stud.getSurname() + " " + stud.getName() + " " + stud.getSerial() + " " + stud.getExamName() + " " + stud.getExamVote()); //debug
				} //end of while
				
			}
		}
		
		ActionListener openDBButtonListener = new openDBButtonListenerClass();
		openDBButton.addActionListener(openDBButtonListener);
		
		
		class exitButtonListenerClass implements ActionListener {
			@Override
			public void actionPerformed (ActionEvent e) {
				System.exit(0);
			}
		}
		
		ActionListener exitButtonListener = new exitButtonListenerClass();
		exitButton.addActionListener(exitButtonListener);
		
		
		
		
		
		class printListButtonListenerClass implements ActionListener {
			@Override
			public void actionPerformed (ActionEvent e) {
				//
			}
		}
		
		ActionListener printListButtonListener = new printListButtonListenerClass();
		printListButton.addActionListener(printListButtonListener);
		
		
		
		
	} //end of main

} //end of class

Qualcuno potrebbe spiegarmi perché, come stanno le cose adesso, usando il metodo addFirst il programma mi restituisce questo errore:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at com_antomau_ListeConcatenate.UserInterface.UserListeConcatenate$1openDBButtonListenerClass.actionPerformed(UserListeConcatenate.java:103)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6533)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6298)
	at java.awt.Container.processEvent(Container.java:2236)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Container.dispatchEventImpl(Container.java:2294)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
	at java.awt.Container.dispatchEventImpl(Container.java:2280)
	at java.awt.Window.dispatchEventImpl(Window.java:2746)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.awt.EventQueue$4.run(EventQueue.java:729)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Grazie in anticipo a quanti mi risponderanno.

9 Risposte

  • Re: Implementare Iteratore per Lista Concatenata

    antomau96 ha scritto:


    ho realizzato una lista concatenata con relativa classe iteratore ma non ho idea su come devo implementare l'iteratore per farlo funzionare.
    Vedo che hai una interfaccia specifica per l'iteratore, questo è assolutamente ok e va bene. Questa interfaccia la dovrai chiaramente implementare da qualche parte. Attenzione: NON è la collezione (nel tuo caso ListaConcatenata) che deve avere direttamente il implements ListIterator .

    Di norma l'iteratore lo si implementa con una classe interna e nascosta (non visibile all'esterno) fatta tipicamente come inner-class privata definita materialmente nella classe della collezione. E poi la collezione espone un metodo pubblico es. iterator() che "tira fuori" una nuova istanza dell'iteratore ma restituendolo come tipo della interfaccia (non della classe specifica).

    A chi usa l'iteratore, infatti non interessa assolutamente dove/come è implementato l'iteratore, purché rispetti il contratto dettato dalla interfaccia dell'iteratore.

    La implementazione dell'iteratore è bene che sia nella classe della collezione, perché deve conoscere i dettagli interni di come è gestita la collezione. All'interno di una istanza dell'iteratore dovrai tenere le informazioni necessarie a "sapere" a che punto è la iterazione e come proseguire.
  • Re: Implementare Iteratore per Lista Concatenata

    Spero di non importunarla troppo,
    potrebbe consigliarmi qualche libro (anche in inglese) che tratta molto bene le strutture dati? (liste, alberi, hashMap, etc...)
  • Re: Implementare Iteratore per Lista Concatenata

    antomau96 ha scritto:


    Spero di non importunarla troppo
    No, anzi, no prob!

    antomau96 ha scritto:


    potrebbe consigliarmi qualche libro (anche in inglese) che tratta molto bene le strutture dati? (liste, alberi, hashMap, etc...)
    Se intendi strutture dati in generale come teoria e principi, a livello più "accademico", in questo momento non ho titoli da segnalarti ma posso cercarne (tieni anche presente che questi sono libri abbastanza particolari e meno noti, quindi tendono a costare un po' ...).

    Se invece intendi l'uso del Collections Framework di Java (e il correlato uso dei "generics"), allora il suggerimento e per (l'unico davvero valido!):
    "Java Generics and Collections" di Maurice Naftalin, Philip Wadler; O'Reilly Media

    Assolutamente un "must" per chi vuole usare almeno Java 5.
  • Re: Implementare Iteratore per Lista Concatenata

    Grazie,
    Si intendo strutture dati e relativa implementazione con esempi pratici su strutture come liste concatenate, alberi di ricerca binari, tabelle hash, generazione di codici di hash...

    Sapresti darmi anche qualche indicazione in merito al libro "Java - Tecniche avanzate di programmazione" di Deitel&Deitel?

    P.S.:
    Te lo chiedo perche sul libro dei fratelli Deitel ho studiato Ansi C e mi sono trovato benissimo...
  • Re: Implementare Iteratore per Lista Concatenata

    Una semplice domanda:

    data l'interfaccia
    package com_antomau_ListeConcatenate.ListIterator;
    import com_antomau_ListeConcatenate.Studente.Studente;
    public interface ListIterator {
    	Studente next();
    	boolean hasNext();
    	void add(Studente element);
    	void remove();
    	void set (Studente element);
    } //end of interface
    che va a definire quello che deve essere l'iteratore per una lista concatenata,
    essa viene implementata nella classe LinkedListIterator

    e poi viene creato il metodo
    /**
    	 * Questo metodo restituisce un iteratore per la lista.
    	 * @return Un iteratore per la lista.
    	 */
    	public ListIterator listIterator()
    	{
    		return new LinkedListIterator();
    	}
    finalizzato alla restituzione di un oggetto del tipo LinkedListIterator.

    Nel metodo main dichiaro una variabile di tipo ListIterator di questo nel modo seguente:
    ListIterator myIterator = myList.listIterator();
    Fin qui nessun errore segnalato da Eclipse ma appena vado ad eseguire il programma compare l'errore
    Exception in thread "main" java.lang.NullPointerException
    	at com_antomau_ListeConcatenate.UserInterface.UserListeConcatenate.main(UserListeConcatenate.java:76)
    
    dove la linea 76 è proprio la dichiarazione della variabile myIterator.

    In che modo devo dichiarare l'iteratore per la classe?
    Non riesco a comprendere minimamente quale sia la causa dell'errore!
  • Re: Implementare Iteratore per Lista Concatenata

    antomau96 ha scritto:


    essa viene implementata nella classe LinkedListIterator
    Sì ma dovrebbe essere dentro la classe della tua collezione, ListaConcatenata

    antomau96 ha scritto:


    Exception in thread "main" java.lang.NullPointerException
    	at com_antomau_ListeConcatenate.UserInterface.UserListeConcatenate.main(UserListeConcatenate.java:76)
    
    dove la linea 76 è proprio la dichiarazione della variabile myIterator.
    myList è inizializzata ad un oggetto ListaConcatenata ??
  • Re: Implementare Iteratore per Lista Concatenata

    Si,
    private static ListaConcatenata myList;
    Per quanto riguarda l'iteratore c'è sempre l'implementazione dell'interfaccia
    import com_antomau_ListeConcatenate.LinkedList.ListaConcatenata.LinkedListIterator;
    import com_antomau_ListeConcatenate.ListIterator.ListIterator;
    Se per capire meglio vuoi consultare il progetto completo ecco il link:
    https://github.com/myblacksloth/javaPrograms/tree/master/LinkedLists-0.1
  • Re: Implementare Iteratore per Lista Concatenata

    antomau96 ha scritto:


    Si,
    private static ListaConcatenata myList;
    Perché "static"? Non va molto bene in generale .... (se non mi dai motivazioni assolutamente importanti per lo static).
    E poi comunque questa è solo la definizione di una variabile "di classe", il cui valore iniziale è null.
    Se da qualche altra parte NON hai un:

    myList = new ......

    allora QUELLO è l'errore.

    antomau96 ha scritto:


    Per quanto riguarda l'iteratore c'è sempre l'implementazione dell'interfaccia
    import com_antomau_ListeConcatenate.LinkedList.ListaConcatenata.LinkedListIterator;
    import com_antomau_ListeConcatenate.ListIterator.ListIterator;
    Ripeto che la implementazione dell'iteratore dovrebbe stare DENTRO la classe della collezione. La implementazione concreta dell'iteratore non deve essere (per forza) nota all'esterno né importata chissà dove.

    antomau96 ha scritto:


    Se per capire meglio vuoi consultare il progetto completo ecco il link:
    https://github.com/myblacksloth/javaPrograms/tree/master/LinkedLists-0.1
    Confermo la mia ipotesi: myList NON è inizializzata esplicitamente.

    E in ListaConcatenata invece di

    public class LinkedListIterator implements ListIterator

    andrebbe

    private class LinkedListIterator implements ListIterator


    Poi

    private Node headList;
    invece che
    public Node headList;


    E anche Node sarebbe meglio private (e da rivedere in generale)
  • Re: Implementare Iteratore per Lista Concatenata

    Mi sono perso su una banalità senza precedenti!
    Non oso neanche pensare a come abbia potuto commettere un errore simile
    Ti ringrazio ancora una volta!

    Ecco il progetto con il fix:
    https://github.com/myblacksloth/javaPrograms/tree/master/LinkedLists/LinkedLists-1-0.2

    Spero di non avere altri problemi e posterò le varie versioni su GitHub per chiunque fosse interessato
Devi accedere o registrarti per scrivere nel forum
9 risposte