View Full Version : [Java] Gestione delle matrici
Nel software su cui sto lavorando ho la necessità di dichiararmi una matrice di interi
int [][]dataMatrix = new int[3][7]
Più avanti nel codice devo determinare se un certo valore è presente o meno all'interno della COLONNA 1, e in quel caso farmi restituire la sua posizione (l'indice).
allora mi sono scritto una funzione di questo tipo:
public int findIndex(int column[], int value)
{
int k = 0;
boolean valueFound = false;
for (k = 0; (k < column.length) || (!valueFound); k++)
{
if (column[k] == value)
{
valueFound = true;
}
}
return (k);
}
il mio problema è su come richiamare tale funzione
Se da codice scrivo:
int index = findIndex(dataMatrix[0], valore)
la funzione mi cerca il valore nella prima RIGA. A me serve invece la prima COLONNA. C'è un modo per specificare la colonna e non la riga?
ho provato con
int index = findIndex(dataMatrix[][0], valore)
ma continua a darmi errore.
Grazie per l'attenzione
Davide
o ti crei la matrice per colonne (cioè quelle che ora solo le colonne diventano le righe e viceversa) oppure modifichi il metodo in modo che riceva l'intera matrice:
public int findIndex(int mat[][], int value){
for (int k = 0; (k < mat.length); k++){
if (mat[k][1] == value)
return k;
}
return -1;
}
Sono di fretta e non entro nel merito del problema, ma a mio avviso avete fatto entrambi alcuni errorini:
@Benna80
1) Inizializzi K=0 e poi nel loop K parte da 0 e alla fine ritorni K: il che vuol dire che presupponi che il valore debba trovarsi sicuramente nell'array, perché altrimenti non riesci a distinguere tra il K=0 perché non hai trovato nulla e il K=0 perché l'hai trovato alla prima
2) metter "|| (!valueFound)" non serve a niente, perché essendo in && non ferma il loop nel caso lo trovassi. Devi metterlo in &&
@anx721
non puoi ritornare k perché l'hai dichiarato nel for ;)
Ovviamente in questo caso è una svista che emerge in compilazione.
Sono di fretta e non entro nel merito del problema, ma a mio avviso avete fatto entrambi alcuni errorini:
@Benna80
1) Inizializzi K=0 e poi nel loop K parte da 0 e alla fine ritorni K: il che vuol dire che presupponi che il valore debba trovarsi sicuramente nell'array, perché altrimenti non riesci a distinguere tra il K=0 perché non hai trovato nulla e il K=0 perché l'hai trovato alla prima
2) metter "|| (!valueFound)" non serve a niente, perché essendo in && non ferma il loop nel caso lo trovassi. Devi metterlo in &&
@anx721
non puoi ritornare k perché l'hai dichiarato nel for ;)
Ovviamente in questo caso è una svista che emerge in compilazione.
Grazie ad entrambi, nel modo suggeritomi da anx721 e con le tue correzioni ho risolto, credevo cmq che si potesse ritornare anche la colonna visto che la riga la ritornava senza problemi.
Ora vi chiedo un'altra cosa, ma non so se è giusto mantenerlo su questo thread dal momento che si tratta di una cosa che non centra nulla con il problema di prima.
Ho una matrice di n x 2 di long. i due valori di ogni riga sono strettamente correlati tra loro. Ora, ho la necessità di ordinare i numeri della prima colonna facendo in modo che se viene spostato un valore, anche il valore della colonna 2 lo segua:
Esempio:
PRIMA DELL'ORDINAMENTO:
1766915 3
12368405 2
10601490 1
devo ordinare la matrice in base alla prima colonna, mantenendo le corrispondenze tra righe:
DOPO L'ORDINAMENTO
12368405 2
10601490 1
1766915 3
Mi è stato suggerito di usare l'oggetto TreeMap, ma sulla documentazione di Sun non c'è scritto un gran che. Mi potreste dare una mano voi, una qualche dritta?
Grazie e scusatemi se non ho aperto un thread apposito, se non mi vorrete rispondere ne farò uno nuovo.
Davide
Se sei in grado di ordinare un array di elementi dovresti essere in grado di ordinare anche la matrice: basta fare i confronti sul primo elemento della riga e quando necessario scambiare le righe nella matrice (il che ti evita di scambiare direttamente entrambi gli elementi delle righe). Se non vuoi implementare l'algoritmo di ordinamento puoi utilizare Collections.sort che prende come parametro una List (ad esempio un Vector) degli elementi da ordinare, in questo caso delle righe, e un Comparator che cofnronta gli elementi.
PS: il codice che avevo scritto prima l'ho corretto; l'ultimo return deve ritornare un valore negativo per indicare che l'elemento non è stato trovato nella colonna.
Se sei in grado di ordinare un array di elementi dovresti essere in grado di ordinare anche la matrice: basta fare i confronti sul primo elemento della riga e quando necessario scambiare le righe nella matrice (il che ti evita di scambiare direttamente entrambi gli elementi delle righe). Se non vuoi implementare l'algoritmo di ordinamento puoi utilizare Collections.sort che prende come parametro una List (ad esempio un Vector) degli elementi da ordinare, in questo caso delle righe, e un Comparator che cofnronta gli elementi.
PS: il codice che avevo scritto prima l'ho corretto; l'ultimo return deve ritornare un valore negativo per indicare che l'elemento non è stato trovato nella colonna.
Grazie tante, domani appena riesco provo, ora sono troppo a pezzi per mettermi a cercare info.
Grazie ancora, ti farò sapere in ogni caso, sia che riesca sia che abbia delle difficoltà
Davide
Ragazzi scusate se mi intrometto ma vedo che siete esperti, ho un problema con i file jsp:
ho fatto un controllo "anti-intrusione" nei miei jsp che controlla se una variabile nell'oggetto session e' settata o meno.
Ovviamente quando entro (login) la setto ad un valore, quando esco (logout) la rimetto a null.
Peccato che se con il browser client faccio logout (e in teoria ora e' a null), poi faccio back e navigo nel mio sito in teoria dovrei essere buttato fuori, in pratica me lo da buono.
Cordice di controllo di ogni jsp:
if ((session.isNew()) || (session.getAttribute("security")==null) || (session.getAttribute("security")!="ProfPass"))
{
%>
<jsp:forward page="loginProf.jsp"/>
<%
}
Codice del logout
<%
session.setAttribute("security",null);
%>
<jsp:forward page="loginProf.jsp"/>
Vi propongo il mio problema con le matrici...
Devo scrivere un programma in java che gestisca un'agenda di appuntamenti.
La mia idea è stata quella di creare una matrice 12 x 31 che rappresenta un anno intero. Ogni casella di questa matrice è un oggetto di LinkedList che a sua volta contiene oggetti di tipo appuntamento in modo ordanato secondo la data.
Il mio problema è questo. Come faccio a fare in modo che ogni lista (oltre agli appuntamenti del giorno che rappresenta) contenga un puntatore alla lista del giorno successivo (cioè la casella successiva) ??
Se avete qualche idea migliore della matrice di liste proponete pure....
Grazie
Obinna :D
@anx721
non puoi ritornare k perché l'hai dichiarato nel for ;)
Ovviamente in questo caso è una svista che emerge in compilazione.
Questa non l'ho capita.
banryu79
20-05-2009, 13:28
La mia idea è stata quella di creare una matrice 12 x 31 che rappresenta un anno intero.
E come faresti per i mesi con meno di 31 giorni? E per i febbrai bisestili (se l'agenda permette di gestire più anni)?
Il mio problema è questo. Come faccio a fare in modo che ogni lista (oltre agli appuntamenti del giorno che rappresenta) contenga un puntatore alla lista del giorno successivo (cioè la casella successiva) ??
Crei un'altra classe che chiamiamo "Giornata": lo stato di Giornata è rappresentato dalla LinkedList di oggetti Appuntamento e da una reference alla Giornata successiva [il che ti permetterebbe di saltare direttamente dal 30 di Aprile all'1 di Maggio, oppure dal 28 di Febbraio all'1 di Marzo].
Quindi le celle della matrice [12x31] verranno popolate da istanze di Giornata.
Scritto di getto: non credo questa sia la migliore astrazione per rappresentare un'agenda. Diciamo che per pensarne una come si deve (sempre ammesso di non andare prima a informarsi di come si sia già implementata un'agenda, dato che presumibilmente è un problema che sarà già stato risolto in maniera ottimale) bisognerebbe prima fare una piccola analisi del problema da risolvere, a partire da una sua descrizione, e vedere che classi saltano fuori, man mano che si sviscera la cosa.
Questa non l'ho capita.
Infatti, ma sarà difficile che ti risponda :D
fbcyborg
01-03-2010, 22:00
Salve a tutti,
stavo cercando qualcosa sull'ordinamento di matrici per colonna ed ho trovato questo thread.
Dal momento che dovrei ordinare una matrice che all'occorrenza può essere anche molto grande (in numero di righe), avrei pensato al merge sort.
Il problema è che a partire dal merge sort per array di interi, ho qualche problema a trasformarlo in merge sort per matrici.
La mia matrice da ordinare è composta da:
1a colonna, int
2a colonna, Date
3a colonna, int
Io vorrei ordinare questa matrice per data (in ordine crescente).
L'algoritmo di partenza sarebbe questo:
public static void mergeSort(int[] arr, int i, int f) {
if(f <= i)
return;
int m = (i+f)/2;
mergeSort(arr, i, m);
mergeSort(arr, m+1, f);
//Merge step
int[] tmp = new int[f-i+1];
int i1 = i, i2 = m+1, j = 0;
while(i1 <= m || i2 <= f)
if(i2 > f || (i1 <=m && arr[i1] <= arr[i2]))
tmp[j++] = arr[i1++];
else
tmp[j++] = arr[i2++];
//Copy back to original array
j = 0;
while(i <= f)
arr[i++] = tmp[j++];
}
public static void mergeSort(int[] arr) {
mergeSort(arr, 0, arr.length-1);
}
Qualcuno mi saprebbe dire come posso modificarlo per la mia esigenza?
Ho fatto qualche prova, ma ho dei problemi, anche con lo "scambio" di righe per esempio.
@anx721
non puoi ritornare k perché l'hai dichiarato nel for ;)
Ovviamente in questo caso è una svista che emerge in compilazione. a me non emerge un bel niente.
banryu79
02-03-2010, 00:14
La classe Date (java.util.Date) implementa l'interfaccia Comparable<Date>.
Significa che, dato un array o collection di oggetti Date, ottieni l'odinamento in ordine ascendente semplicemente invocando:
List<Date> mieDate;
// Date[] arrDate;
...
Collections.sort(mieDate);
// Arrays.sort(arrDate);
L'algoritmo dietro le quinte del metodo sort di Collections, è proprio un merge sort leggermente modificato (e se il numero degli elementi è minore di 8 viene invece eseguito un insertion sort).
Detto questo, io tenterei di sfruttare ciò che il JDK mette già a disposizione (se lo scopo non è quello dell'esercitarsi).
Io vedo due strade.
1 - se i campi nelle tre colonne (int, Date, int) rappresentano dati che possono essere raggrupati logicamente in un oggetto, potresti implementare una classe che estende Date e ha due campi di tipo int o Integer.
A quel punto tratti una riga come un oggetto sifatto, hai che la tua classe estendendo Date già implementa l'interfaccia Comparable e quindi una eventuale collezione/array di questi oggetti (le righe della tua matrice) è passabile come argomento al metodo Collections.sort() per ottenere l'ordinamento in senso ascendente.
Se poi servisse averlo in senso descrescente basta passare la lista ordinata a Collections.reverse() oppure definire un Comparator apposito.
Con in più la possibilità di poter sovvrascrivere il metodo compareTo già fornito da Date per tenere conto anche del caso in cui hai due o più oggetti con Date dello stesso valore (non so se può succedere) e quindi dover discriminare anche in base al valore dei due campi int.
2 - se i campi delle tre colonne (int, Date, int) non possono essere raggruppati in un unico oggetto, si può comunque sfruttare Collections.sort() vedendo la 2a colonna come una lista di oggetti Date ognuno associato al valore dell'indice della posizione che occupa nella lista (numero di riga corrente); questo può essere rappresentato da una classe che contiene due campi: uno per Date e uno per l'indice.
Si fa il sort di questa lista e la si rilegge con un ciclo recuperando i valori degli indici riordinati che indicano il nuovo ordine delle righe della matrice.
banryu79
02-03-2010, 00:15
a me non emerge un bel niente.
Asd, fero86 pure tu :asd:, ma basta quotare roba di cinque anni fa :tapiro::Prrr:
Asd, fero86 pure tu :asd:, ma basta quotare roba di cinque anni fa :tapiro::Prrr: oddio, necroposting :asd:
non me ne ero minimamente accorto :sbonk:
fbcyborg
02-03-2010, 20:45
banryu79 grazie per la risposta.
No, lo scopo non è quello di esercitarsi. :)
I dati nelle tre colonne non possono essere raggruppati purtroppo, o meglio, non mi conviene usare gli oggetti in questo caso. Vorrei lavorare con le matrici direttamente.
Es.
1 10/05/2010 33
4 11/12/2009 45
5 07/02/2010 39
Dovrebbe riordinarmeli così:
4 11/12/2009 45
5 07/02/2010 39
1 10/05/2010 33
Niente di diverso dall'ordinamento per colonna implementato nelle JTable, e nei fogli di calcolo.
Quello che mi sembra strano è che non ci sia qualcosa di già pronto nelle API Java.
fbcyborg
02-03-2010, 22:12
Dunque, ho cercato di adattare il merge sort al moi caso:
import java.sql.Date;
import java.util.GregorianCalendar;
public class Sorting {
public static void mergeSort(Object[][] o, int i, int f) {
if(f <= i)
return;
int m = (i+f)/2;
mergeSort(o, i, m);
mergeSort(o, m+1, f);
//Merge step
Object[][] tmp = new Object[f-i+1][3];
int i1 = i, i2 = m+1, j = 0;
while(i1 <= m || i2 <= f)
if(i2 > f || (i1 <=m && ((Date)o[i1][1]).compareTo((Date)o[i2][1]) <= 0)){
tmp[j++][0] = o[i1++][0];
tmp[j++][1] = o[i1++][1];
tmp[j++][2] = o[i1++][2];
}else{
tmp[j++][0] = o[i2++][0];
tmp[j++][1] = o[i2++][1];
tmp[j++][2] = o[i2++][2];
}
//Copy back to original array
j = 0;
while(i <= f){
o[i++][0] = tmp[j++][0];
o[i++][1] = tmp[j++][1];
o[i++][2] = tmp[j++][2];
}
}
public static void mergeSort(Object[][] o) {
mergeSort(o, 0, o.length-1);
}
public static void main(String[] args){
Object[][] o = new Object[3][3];
o[0][0] = 1; o[0][1] = new Date((new GregorianCalendar(2010, 9, 1)).getTimeInMillis()); o[0][2] = 15;
o[1][0] = 2; o[1][1] = new Date((new GregorianCalendar(2009, 10, 1)).getTimeInMillis()); o[1][2] = 16;
o[2][0] = 3; o[2][1] = new Date((new GregorianCalendar(2008, 9, 1)).getTimeInMillis()); o[2][2] = 17;
stampa(o);
mergeSort(o);
System.out.println();
stampa(o);
}
public static void stampa(Object[][] a){
for (int i=0;i<a.length;i++){
for (int j=0; j<a[0].length; j++)
System.out.print(a[i][j]+" ");
System.out.println();
}
}
}
Se provate ad eseguire il codice ottenete un:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Sorting.mergeSort(Sorting.java:24)
at Sorting.mergeSort(Sorting.java:11)
at Sorting.mergeSort(Sorting.java:36)
at Sorting.main(Sorting.java:45)
Non riesco a capire perché accada.
Ho fatto il caso specifico che serve a me, ovvero l'ordinamento di una matrice n righe x 3 colonne, in cui la seconda colonna è una data.
Mi sapete dare una mano?
Se serve il merge sort "originale" dal quale sono partito non avete che da chiedere.
fbcyborg
03-03-2010, 14:24
Alla fine ho fatto come hai detto, banryu79!
Ho raggruppato le righe della matrice in oggetti, e ho usato il merge sort appena postato per ordinare l'array di quegli oggetti, in base ad un campo. (Piccola modifica al merge sort che ho postato prima).
A quel punto ho ritrasformato l'array di oggetti in matrice ed il gioco è fatto.
Grazie! :) Mi hai dato una dritta davvero utile!
TorpedoBlu
04-03-2010, 10:33
1) in java si programma ad oggetti, queste porcherie procedurali lasciamole a chi sviluppa C
2) per accedere puntualmente era meglio usare una hash + arraylist (classica lista di adiacenze che rappresenta il grafo) e poi scegliere quale algoritmo usare per la ricerca (ordinamento topografico + algo di ricerca)
3) testiamo la classe con junit con vari input per vedere le performance e ci accorgiamo quanto sia performante ( dove input > 1k numeri )
4) riuso del codice? usare dei comparatori ad hoc, interfacce e gestire il codice in modo più modulare
(se interessato posso postare esempi)
fbcyborg
04-03-2010, 10:39
No no, grazie! :) ho risolto, va bene così! :D
Ho altre gatte da pelare ora.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.