PDA

View Full Version : [Java] Problema con i Comparable


Balop
01-07-2009, 12:29
Ciao, ho un esercizio in cui devo fare una funzione statica per trovare il minimo tra i massimi di ciascuna riga di una matrice di oggetti Comparable passata come argomento.
Io però ho un piccolo problemino con i comparable... vi posto la bozza del programma che ho fatto così capirete da soli, se qualcuno mi può dare una mano... :rolleyes:


public static int Minimo(Comparable mat[][]) {
Comparable min, v[];
Comparable max;
for (int j = 0; j < mat.length; j++) {
max = mat[j][0];
for (int k = 0; k < mat[0].length - 1; k++) {
v[j] = max;
if (max.compareTo(mat[j][k + 1]) == -1)
max = v[j] = mat[j][k + 1];
}
}

min = v[0];
for (int i = 1; i < v.length - 1; i++) {
if (min.compareTo(v[i] == -1))
min = v[i];
}

return min;
}

PGI-Bis
01-07-2009, 14:34
Non vedo l'inizializzazione di v[], manca qualche parentesi, il metodo dichiara la restituzione di un int ma tenta di restituire un Comparable.

Per il resto i Comparable funzionano quasi come pensi: non restituiscono -1, 0 o 1 ma un valore minore di zero, uguale a zero o maggiore di zero nei casi minore, uguale, maggiore. Può essere -1, può essere -2000: conta il segno.

Anzichè dire if(a.compareTo(b) == -1) devi dire if(a.compareTo(b) < 0) e, analogamente per il caso maggiore, if(a.compareTo(b) > 0) anzichè if(a.compareTo(b) == 1).

L'algoritmo è corretto

Balop
01-07-2009, 14:46
Non vedo l'inizializzazione di v[], manca qualche parentesi, il metodo dichiara la restituzione di un int ma tenta di restituire un Comparable.

Per il resto i Comparable funzionano quasi come pensi: non restituiscono -1, 0 o 1 ma un valore minore di zero, uguale a zero o maggiore di zero nei casi minore, uguale, maggiore. Può essere -1, può essere -2000: conta il segno.

Anzichè dire if(a.compareTo(b) == -1) devi dire if(a.compareTo(b) < 0) e, analogamente per il caso maggiore, if(a.compareTo(b) > 0) anzichè if(a.compareTo(b) == 1).

L'algoritmo è corretto

mi aveva detto il prof che i comparable funzionavano così... :muro:
ho fatto al volo qualche correzione come mi hai suggerito:
public static Comparable Minimo(Comparable mat[][]) {
Comparable min, max;
Comparable v[] = new Comparable [mat.length];

for (int j = 0; j < mat.length; j++) {
max = mat[j][0];
for (int k = 0; k < mat[0].length - 1; k++) {
v[j] = max;
if (max.compareTo(mat[j][k + 1]) < 0)
max = v[j] = mat[j][k + 1];
}
}

min = v[0];
for (int i = 1; i < v.length - 1; i++) {
if (min.compareTo(v[i] < 0))
min = v[i];
}

return min;
}

ma mi segna ancora in rosso la parte v[i] < 0 dell'ultimo ciclo for..

intanto grazie x la risposta :)

PGI-Bis
01-07-2009, 14:48
C'è una parentesti al posto sbagliato.

Da così:

if (min.compareTo(v[i] < 0))

a così:

if (min.compareTo(v[i]) < 0)

Balop
02-07-2009, 09:45
thank you a PGI-Bis, il programma finito è questo:
public static Comparable minimo(Comparable mat[][]) {
Comparable min, max;
Comparable v[] = new Comparable[mat.length];

for (int j = 0; j < mat.length; j++) {
max = mat[j][0];
for (int k = 1; k < mat[0].length; k++) {
v[j] = max;

if (max.compareTo(mat[j][k]) < 0) {
max = v[j] = mat[j][k];

}
}
}

min = v[0];
for (int i = 1; i < v.length; i++) {
if (min.compareTo(v[i]) > 0)
min = v[i];
}
System.out.println(min);
return min;
}

Balop
02-07-2009, 11:58
Scusate avrei l'ultimo esercizio da svolgere.. però qua non so dove mettere le mani prima.. il testo è questo:
Scrivere il codice di una semplice funzione statica ricorsiva che ritorni il valore più piccolo presente in un albero binario di oggetti Comparable.
ora, essendo l'albero binario già ordinato, dovrei scorrere solo nel ramo sinistro, confrontare i valori e prendere il minore... ma come potrei scorrere nel ramo sinistro? :mc:

PGI-Bis
02-07-2009, 12:48
Be', vai sempre a sinistra.

Ogni nodo del tuo albero avrà al più due figli, il destro e il sinistro. Avrai quindi una funzione tipo:

Valore getMinimo(Nodo n)
se n->left == null return n.valore
altrimenti return getMinimo(n.left);

Balop
02-07-2009, 14:33
Be', vai sempre a sinistra.

Ogni nodo del tuo albero avrà al più due figli, il destro e il sinistro. Avrai quindi una funzione tipo:

Valore getMinimo(Nodo n)
se n->left == null return n.valore
altrimenti return getMinimo(n.left);

dovrei presupporre di avere nodi di questo tipo no?
private class BinNode {
private Object key;
private BinNode left;
private BinNode right;
private BinNode parent;


BinNode( Object c, BinNode sx, BinNode dx, BinNode g ) {
key = c;
left = sx;
right = dx;
parent = g;

if (sx != null)
sx.parent = this;
if (dx != null)
dx.parent = this;
}
}

e per scorrere sempre verso sinistra che codice dovrei usare?
come hai scritto tu, in un nodo prendo il valore minimo, ma io dovrei fare un codice ricorsivo che controlla tutti i nodi e prenda il minimo fra tutti i valori...

PGI-Bis
02-07-2009, 14:44
Se l'albero è ordinato e il criterio di ordinamento colloca a sinistra il valore minore allora il minimo è la foglia più a sinistra che hai.

La funzione ricorsiva:

Comparable getMinimum(Nodo n) {
if(n.getLeft() != null) return getMinimum(n.getLeft());
else return n.getValue();
}

fa esattamente questo: scende più a sinistra che può e quando arriva alla foglia più a sinstra che c'è, PAF, restituisce il suo valore. Un albero ordinato in tal modo lo ottieni quando l'inserimento di un valore nella radice ha la forma:

public void add(Comparable v) {
if(v.compareGetValue() < 0) {
//aggiungi v a left
} else {
//aggiungi v a right
}
}

Balop
02-07-2009, 14:54
ok, recepito il messaggio!!!
thank you very much per il supporto tecnico!!! :D

banryu79
02-07-2009, 15:04
void add(Comparable key)
{
BinNode newNode = new BinNode(key);
BinNode father = null, temp = this;

// trova il padre per il nuovo nodo
while (temp != null)
{
father = temp;
if (newNode.key.compareTo(temp.key) < 0)
temp = temp.left;
else
temp = temp.right;
}

newNode.parent = father;

// inserisce il nuovo nodo a destra o a sinistra del padre
if (newNode.key.compareTo(father.key) < 0)
father.left = newNode;
else
father.right = newNode;
}


Esempio:
BinNode root = new BinNode(new Integer(8));
root.add(new Integer(4)); // lo aggiunge come figlio sinistro di root
root.add(new Integer(10)); // lo aggiunge come figlio destro di root

la classe BinNode deve accettare Comparable e quindi la chiave (key) deve essere di tipo Comparable.