Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere?
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere?
Equilibrio e potenza definiscono il Samsung Galaxy S26+, un flagship che sfida la variante Ultra e la fascia alta del mercato con il primo processore mobile a 2nm. Pur mantenendo l'hardware fotografico precedente, lo smartphone brilla per un display QHD+ da 6,7 pollici d'eccellenza, privo però del trattamento antiriflesso dell'Ultra, e per prestazioni molto elevate. Completano il quadro la ricarica wireless a 20W e, soprattutto, un supporto software settennale
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti
Zeekr sbarca ufficialmente in Italia con tre modelli elettrici premium, X, 7X e 001, distribuiti da Jameel Motors su una rete di 52 punti vendita già attivi. La Zeekr X parte da 39.900 euro, la 7X da 54.100: piattaforma a 800V, chip Snapdragon di ultima generazione, ricarica ultraveloce e un'autonomia dichiarata fino a 615 km WLTP. Le prime consegne sono previste a metà aprile
Marathon: arriva il Fortnite hardcore
Marathon: arriva il Fortnite hardcore
Marathon è il titolo multiplayer competitivo del momento. Ecco quali sono le caratteristiche di gioco principali, insieme alle nostre prime considerazioni dopo qualche "run" nell'extraction shooter di Bungie
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 19-01-2015, 13:12   #1
Giobbo
Member
 
Iscritto dal: Aug 2013
Messaggi: 42
[Java] Scelta struttura dati

Buongiorno a tutti.
Scrivo perché mi sto esercitando con Java e, dopo aver fatto un po' di teoria, vorrei eseguire un esercizio un po' complesso per vedere cosa sono in grado o meno di fare.
Peccato che, pronti via, sono andato un po' nel pallone.
Nell'esercizio che ho preso in considerazione mi si chiede di creare una struttura dati adatta a supportare una rete metropolitana. In particolare, devo essere in grado di stampare le fermate (divise per linea) e aggiungere o togliere una fermata e/o un collegamento tra fermate.

Chiaramente la struttura dati adatta per farlo è un grafo (o sbaglio).
Qui sorge il dubbio: implementato come?
Innanzitutto, ecco la classe Fermata, che chiaramente modella le singole fermate, di cui vi mostro i campi (giusto per far capire):

Codice:
public class Fermata {
     
     private String nome;
     private ArrayList<Linea> linea;
     private boolean capolinea}
L'attributo linea è costituito da un ArrayList perché una singola fermata può appartenere a più linee.
E poi la classe Linea:

Codice:
public class Linea {
     
     private int numero;
     private int num_fermate;
     private Fermata capolinea;}
Ora, tornando al problema posto.
L'intera "mappa" delle fermate io avevo pensato di farla tramite l'utilizzo di un HashMap, dove le chiavi fossero le varie fermate e i valori riferiti fossero l'insieme di archi che rappresentano i collegamenti tra la fermata (che fa da chiave) e le altre.
E' un procedimento corretto? Troppo complesso? Troppo semplice? Ve ne sono di migliori?
Se come idea va bene, sorge una ulteriore domanda: come faccio, se è possibile, a fare in modo che la chiave sia identificata solamente dal campo contenente il nome della fermata?
Questo in modo che sia possibile accedere sia alle altre informazioni contenute nella chiave (come la lista delle linee di appartenenza o il fatto che sia capolinea o meno) sia chiaramente ai valori riferiti?

Spero mi sia espresso in modo abbastanza chiaro.
Grazie in anticipo a chi avrà la voglia e la pazienza di rispondermi.
Giobbo è offline   Rispondi citando il messaggio o parte di esso
Old 20-01-2015, 09:26   #2
Oceans11
Senior Member
 
L'Avatar di Oceans11
 
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
Quote:
Originariamente inviato da Giobbo Guarda i messaggi
Chiaramente la struttura dati adatta per farlo è un grafo (o sbaglio).
Qui sorge il dubbio: implementato come?
Un grafo potrebbe essere una struttura dati adatta, ma non è l'unica.
Inutile parlare di migliore o peggiore, dipende dalla propria conoscenza e dal tipo di astrazione si vuole dare.
Tu devi "astrarre" il problema e trovare la tua soluzione. Solo dopo puoi chiederti se si può migliorare e come.
I grafi normalmente vengono astratti con matrici di adiacenza, incidenza o liste di adiacenza.

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
Innanzitutto, ecco la classe Fermata, che chiaramente modella le singole fermate, di cui vi mostro i campi (giusto per far capire):
Codice:
public class Fermata {
     private String nome;
     private ArrayList<Linea> linea;
     private boolean capolinea}
L'attributo linea è costituito da un ArrayList perché una singola fermata può appartenere a più linee.
Una fermata può essere capolinea per una linea sì e per un'altra no?
(se la risposta è sì, allora un unico boolean non basta )

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
E poi la classe Linea:
Codice:
public class Linea {
     private int numero;
     private int num_fermate;
     private Fermata capolinea;}
Una linea ha un solo capolinea? Se la riposta è no, un solo capolinea ovviamente non basta.
Per come la vedo io, una Linea ha l'informazione dell'insieme di Fermate. (st'info ti manca)

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
L'intera "mappa" delle fermate io avevo pensato di farla tramite l'utilizzo di un HashMap, dove le chiavi fossero le varie fermate e i valori riferiti fossero l'insieme di archi che rappresentano i collegamenti tra la fermata (che fa da chiave) e le altre.
E' un procedimento corretto? Troppo complesso? Troppo semplice? Ve ne sono di migliori?
Va benissimo "mappare" le fermate e il ragionamento fila, ma hai ben chiaro che vuol dire "i valori riferiti fossero l'insieme di archi che rappresentano i collegamenti tra fermate"? ecco che entrano in gioco le liste di adiacenza

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
Se come idea va bene, sorge una ulteriore domanda: come faccio, se è possibile, a fare in modo che la chiave sia identificata solamente dal campo contenente il nome della fermata?
Questo in modo che sia possibile accedere sia alle altre informazioni contenute nella chiave (come la lista delle linee di appartenenza o il fatto che sia capolinea o meno) sia chiaramente ai valori riferiti?
Non credo di aver capito la domanda.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes]
"Pirating software? Choose Microsoft!"
Oceans11 è offline   Rispondi citando il messaggio o parte di esso
Old 20-01-2015, 21:04   #3
Giobbo
Member
 
Iscritto dal: Aug 2013
Messaggi: 42
Innanzitutto ti ringrazio per la risposta.
Vado con ordine.

Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Una fermata può essere capolinea per una linea sì e per un'altra no?
(se la risposta è sì, allora un unico boolean non basta )
Hai ragione, non ci avevo pensato.
Una soluzione potrebbe essere una classe Capolinea formata da due campi, un boolean per stabilire se la fermata è o meno un capolinea e un int che identifica (nel caso la fermata sia effettivamente un capolinea) la linea per cui lo è (a cui potrei dare un valore di default se la fermata non è un capolinea).

Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Una linea ha un solo capolinea? Se la riposta è no, un solo capolinea ovviamente non basta.
Per come la vedo io, una Linea ha l'informazione dell'insieme di Fermate. (st'info ti manca)
L'insieme delle fermate non l'ho messa come informazione perché sarebbe ridondante rispetto agli archi (di giù mi spiego meglio).
Il capolinea singolo mi serve solamente per iniziare a visitare i nodi del mio grafo (quindi le fermate) da uno in particolare.

Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Va benissimo "mappare" le fermate e il ragionamento fila, ma hai ben chiaro che vuol dire "i valori riferiti fossero l'insieme di archi che rappresentano i collegamenti tra fermate"? ecco che entrano in gioco le liste di adiacenza
Ho proceduto in questo modo.
Ho creato un HashMap del tipo <String, HashSet<Tratta>>; dove String è il nome della fermata e l'HashSet è l'insieme delle tratte (banalmente, da quella fermata ad un altra) che la coinvolgono. Un oggetto Tratta è fatto di questi campi:

Codice:
private String fermata_collegata; // fermata collegata tramite la tratta
private int linea; // linea di cui fa parte la tratta, visto che due fermate possono essere collegate da più linee
private int lunghezza; // durata della tratta, ovvero peso dell'arco
Le fermate le distinguo esclusivamente tramite stringhe perché, oltre al'HashMap descritto sopra, ne utilizzo un secondo che collega il nome della fermata con le sue informazioni (quindi del tipo <String, Fermata>).

Per quanto riguarda l'ultima domanda che non hai capito, chiedevo se fosse possibile utilizzare un HashMap del tipo <Fermata, HashSet<Tratta>> (in modo da non dover utilizzare du HashMap) ma recuperare informazioni della chiave e del valore corrispondente attraverso esclusivamente un campo specifico dell'oggetto Fermata (ovvero il nome).
Giobbo è offline   Rispondi citando il messaggio o parte di esso
Old 21-01-2015, 10:50   #4
Oceans11
Senior Member
 
L'Avatar di Oceans11
 
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
Quote:
Originariamente inviato da Giobbo Guarda i messaggi
Una soluzione potrebbe essere una classe Capolinea formata da due campi, un boolean per stabilire se la fermata è o meno un capolinea e un int che identifica (nel caso la fermata sia effettivamente un capolinea) la linea per cui lo è (a cui potrei dare un valore di default se la fermata non è un capolinea).
La classe Capolinea è una buona idea e viene naturale pensarla come sottoclasse di Fermata, non credi?
I dettagli implementativi sono sempre relativi alla quantità di informazioni che vuoi rappresentare nel programma. Ad esempio, una fermata può essere capolinea per una linea e una fermata qualsiasi per un'altra. (non voglio complicarti la vita, solo esporre le possibilità).

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
L'insieme delle fermate non l'ho messa come informazione perché sarebbe ridondante rispetto agli archi (di giù mi spiego meglio).
Il capolinea singolo mi serve solamente per iniziare a visitare i nodi del mio grafo (quindi le fermate) da uno in particolare.
Va bene se l'info delle fermate la ricavi solo dagli archi. Ma allora la classe che gestisce gli archi di una linea io la chiamerei Linea, mentre la classe che gestisce l'intero grafo la chiamerei ReteMetropolitana. Nel rispetto della OOP che mantiene alto il livello di astrazione. (spero di essere stato chiaro)

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
Ho proceduto in questo modo.
Ho creato un HashMap del tipo <String, HashSet<Tratta>>; dove String è il nome della fermata e l'HashSet è l'insieme delle tratte (banalmente, da quella fermata ad un altra) che la coinvolgono. Un oggetto Tratta è fatto di questi campi:

Codice:
private String fermata_collegata; // fermata collegata tramite la tratta
private int linea; // linea di cui fa parte la tratta, visto che due fermate possono essere collegate da più linee
private int lunghezza; // durata della tratta, ovvero peso dell'arco
Le fermate le distinguo esclusivamente tramite stringhe perché, oltre al'HashMap descritto sopra, ne utilizzo un secondo che collega il nome della fermata con le sue informazioni (quindi del tipo <String, Fermata>).
Ah ora ho capito, quindi per ricostruirti la linea in sostanza tu interroghi l'hashmap dal capolinea fino a che non hai trovato tutte le fermate nelle tratte.
Io onestamente avrei utilizzato un ArrayList<Fermate>, ma non dico che sarebbe stato meglio.

Quote:
Originariamente inviato da Giobbo Guarda i messaggi
Per quanto riguarda l'ultima domanda che non hai capito, chiedevo se fosse possibile utilizzare un HashMap del tipo <Fermata, HashSet<Tratta>> (in modo da non dover utilizzare du HashMap) ma recuperare informazioni della chiave e del valore corrispondente attraverso esclusivamente un campo specifico dell'oggetto Fermata (ovvero il nome).
Ok, ci sono! E si può fare.
Devi fare l'override di hashCode() della classe Fermata (e di equals() perchè i due devono essere consistenti) e calcolarlo solo in base alle info che ti servono (ovvero il nome)
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes]
"Pirating software? Choose Microsoft!"
Oceans11 è offline   Rispondi citando il messaggio o parte di esso
Old 21-01-2015, 12:40   #5
Giobbo
Member
 
Iscritto dal: Aug 2013
Messaggi: 42
Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
La classe Capolinea è una buona idea e viene naturale pensarla come sottoclasse di Fermata, non credi?
I dettagli implementativi sono sempre relativi alla quantità di informazioni che vuoi rappresentare nel programma. Ad esempio, una fermata può essere capolinea per una linea e una fermata qualsiasi per un'altra. (non voglio complicarti la vita, solo esporre le possibilità).
Sì, direi che la sottoclasse è la soluzione migliore e più ovvia.

Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Ah ora ho capito, quindi per ricostruirti la linea in sostanza tu interroghi l'hashmap dal capolinea fino a che non hai trovato tutte le fermate nelle tratte.
Io onestamente avrei utilizzato un ArrayList<Fermate>, ma non dico che sarebbe stato meglio.
Mmmm.
Ma l'ArrayList<Fermate> intendi al posto dell'HashMap<Tratta>?
Oppure creare, nella classe principale che gestisce la mappa intera (quello che hai citato tu, ReteMetropolitana), oltre alle HashMap delle tratte e delle info delle varie fermate un'ulteriore HashMap del tipo <Linea, ArrayList<Fermate>> (ovvero che ad ogni linea associa la lista delle sue fermate?)

Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Ok, ci sono! E si può fare.
Devi fare l'override di hashCode() della classe Fermata (e di equals() perchè i due devono essere consistenti) e calcolarlo solo in base alle info che ti servono (ovvero il nome)
Ho capito.
E, perdona la domanda diretta, come si fa?
Provo a scriverti qualcosina, giusto per farmi dire "NO, non così"
Allora, se non ho capito male i metodi hashcode() e equals() dovrei inserirli all'interno della classe Fermata (ovvero la classe che vorrei utilizzare come chiave). E per fare in modo che l'hashcode sia calcolato solo in base al nome della mia fermata, potrei fare:

Codice:
public int hashcode()
    int risultato;
    risultato =  this.nome.hashcode(); // dove this.nome è la stringa che contiene il nome della fermata
    return risultato;
Per il metodo equals della classe Fermata poi farei la stessa cosa, confrontando solamente le stringhe che contengono il nome della mia fermata.
Corretto?

Due domande.
Una volta messo l'oggetto Fermata come chiave, è possibile modificare i valori dei campi che formano l'oggetto (tolto chiaramente il nome della Fermata)?
Mi spiego con un esempio: stavo pensando di inserire un colore nella mia classe che utilizzerei poi per effettuare visite in ampiezza (e/o profondità). Potrei andare a aggiornare il valore di tale campo anche se l'oggetto Fermata è utilizzato come chiave?

Seconda domanda: siccome alla fine della costruzione della mia struttura dati, dovrei effettuare una ricerca dei possibili percorsi che collegano due fermate date, la struttura dati che sto portando avanti è funzionale in questo senso? O è troppo complicata?
Nel caso lo sia, come potrei farla migliore? (non voglio la pappa pronta eh, chiedo solo dei suggerimenti).

Ultima modifica di Giobbo : 21-01-2015 alle 15:10.
Giobbo è offline   Rispondi citando il messaggio o parte di esso
Old 21-01-2015, 16:17   #6
Oceans11
Senior Member
 
L'Avatar di Oceans11
 
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
ti rispondo solo ad alcune domande per adesso perchè sono a corto di tempo.

Quote:
Allora, se non ho capito male i metodi hashcode() e equals() dovrei inserirli all'interno della classe Fermata (ovvero la classe che vorrei utilizzare come chiave). E per fare in modo che l'hashcode sia calcolato solo in base al nome della mia fermata, potrei fare:

Codice:
public int hashcode()
int risultato;
risultato = this.nome.hashcode(); // dove this.nome è la stringa che contiene il nome della fermata
return risultato;
Per il metodo equals della classe Fermata poi farei la stessa cosa, confrontando solamente le stringhe che contengono il nome della mia fermata.
Corretto?
Corretto. (Per equals cerca online le implementazioni tipo, che inizialmente si fanno controlli su tipo della classe e su parametri null)

Quote:
Una volta messo l'oggetto Fermata come chiave, è possibile modificare i valori dei campi che formano l'oggetto (tolto chiaramente il nome della Fermata)?
Mi spiego con un esempio: stavo pensando di inserire un colore nella mia classe che utilizzerei poi per effettuare visite in ampiezza (e/o profondità). Potrei andare a aggiornare il valore di tale campo anche se l'oggetto Fermata è utilizzato come chiave?
Sì, proprio grazie alla modifica consistente di equals.
Immagina questo, cosa fa la jvm quando ti deve far aggiornare il valore di un campo di Fermata? Cerca la chiave nella mappa. E come la cerca? equals e hashcode che tu hai sovrascritto!

Quote:
Seconda domanda: siccome alla fine della costruzione della mia struttura dati, dovrei effettuare una ricerca dei possibili percorsi che collegano due fermate date, la struttura dati che sto portando avanti è funzionale in questo senso? O è troppo complicata?
Nel caso lo sia, come potrei farla migliore? (non voglio la pappa pronta eh, chiedo solo dei suggerimenti).
Complicata no. Migliore, in termini di prestazioni, non te lo saprei dire su due piedi.

Appena ho tempo rispondo anche alle altre domande, per quel che so.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes]
"Pirating software? Choose Microsoft!"
Oceans11 è offline   Rispondi citando il messaggio o parte di esso
Old 21-01-2015, 20:05   #7
Giobbo
Member
 
Iscritto dal: Aug 2013
Messaggi: 42
Ti ringrazio nuovamente.
Al momento, ho optato per questo tipo di struttura:

Codice:
class Mappa {

    private ArrayList<Linea> linee; // salvo le varie linee con relative informazioni
    private HashMap<String, Fermata>; // associo alla fermata le relative informazioni
    private HashMap<String, HashSet<Tratta>> // associo alla fermata tutte le tratte che la coinvolgono

    ...
Ora dovrei implementare queste operazioni:

- carica Mappa, che consiste nel caricare una mappa da file (con formato prestabilito, dato come argomento): su questo sono già a posto.

- visualizza, che consiste nel visualizzare tutte le fermate di una linea (la numero n data come argomento): pensavo di fare così. Parto dal capolinea (salvato come ti ho detto nell'oggetto Linea) e cerco tra le sue tratte quella relativa alla linea che voglio stampare. Una volta trovata, stampo la fermata "di arrivo" di tale tratta e passo a cercare tra le tratte di quest'ultima una tratta relativa alla linea che voglio stampare in cui la fermata di arrivo non sia uguale a quella precedente.
Esempio: abbiamo le fermate A---B---C---D della linea 5. Stampo A; cerco tra le sue tratte e trovo "-->B, linea 5"; stampo B; cerco tra le tratte di B, trovo "-->A, linea 5" e "-->C, linea 5", la prima no perché A è la fermata da cui sono arrivato; stampo C; e così via...

- inserisci Tratta, che consiste nell'inserire una nuova tratta (dando come argomenti le due fermate, la linea e la durata della tratta): banalmente, inserisco la tratta negli insiemi delle due fermate coinvolte.

- inserisci Fermata, che consiste nell'inserire una nuova fermata: altrettanto banalmente, aggiungo tale fermata sia nel HashMap delle info che in quello relativo alle varie tratte

- cancella Tratta, che consiste nel cancellare una tratta (come argomento ho le due fermate coinvolte e la linea): anche qui, basta che vado a cercare la tratta negli insiemi delle due fermate e la cancello

- cancella Fermata, che consiste nel cancellare una fermata: cancello la relativa chiave (e di conseguenza i valori associati) dale due HashMap. Dopodichè, scorro l'HashMap relativo alle tratte e cancello tutte quelle in cui la fermata di arrivo è quella che ho cancellato.

- controlla, che consiste nel controllare la mappa e verificare non ci siano linee con biforcazioni: ho pensato che basta vedere se una Fermata ha tre tratte relative ad una linea, visto che può essere collegata solamente a due fermate per essere "regolare".

- percorsi, che consiste nel trovare tutti i percorsi possibili tra due fermate (date come argomento): qui ho difficoltà. Come posso fare? In pratica si dovrebbe implementare la visita in ampiezza (o profondità), giusto? Ma come fare con la struttura dati che utilizzo.

Ti ringrazio in anticipo per la pazienza e la disponibilità.
Giobbo è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere? Recensione Samsung Galaxy S26+: sfida l'Ultra, m...
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti Zeekr X e 7X provate: prezzi, autonomia fino a 6...
Marathon: arriva il Fortnite hardcore Marathon: arriva il Fortnite hardcore
HP Imagine 2026: abbiamo visto HP IQ all’opera, ecco cosa può (e non può) fare HP Imagine 2026: abbiamo visto HP IQ all’opera, ...
PNY RTX 5080 Slim OC, sembra una Founders Edition ma non lo è PNY RTX 5080 Slim OC, sembra una Founders Editio...
NASA: lanciata la missione Artemis II ve...
Intel riacquista la Fab 34 in Irlanda, u...
SpaceX ha lanciato la missione Transport...
Occhiali smart in affitto: la nuova stra...
L'aeroplano supersonico ''silenzioso'' N...
Il primo chip a 2 nm di MediaTek sarà a...
Blue Origin lancerà il satellite ...
Roscosmos torna a lanciare capsule verso...
La connettività satellitare anche sui di...
Astronauta italiano sul suolo lunare gra...
Senza formazione ai dipendenti l'IA non ...
Google rende disponibile l'opzione per i...
Oracle licenzia migliaia di persone con ...
Il semaforo bianco sta arrivando: cos'è,...
FRITZ!Repeater 2700 disponibile su Amazo...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 05:25.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v