|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
[PHP] Perchè mi dice che stò chiamando una funzione non definita ?!?!
Quando provo a far girare la seguente classe con un esempio (inserito subito sotto la fine della classe) mi dà il seguente messagio di errore: Fatal error: Call to undefined function sinistro() in C:\xampp\htdocs\PHPEsempi\algoritmiOrdinamento\Heap.php on line 43
La linea di codice incriminata è: Codice:
if(sinistro($nodo_i) > $this->$heapSize) return; Codice:
<?php
/* Classe che implementa la struttura dati HEAP e la sua funzionalità per
l'ordinamento di una collezione mediante l'algoritmo di ordinamento
Heap Sort */
class Heap{
/* Variabile di istanza che implementa la struttura dati ad albero
dell'heap per mezzo di un array */
private $heap = array();
private $heapSize = 0; // Numero di elementi correntemente dentro l'HEAP
/* Costruttore: Crea un nuovo oggetto istanza di Heap. Riceve un qualunque
array come parametro di input, lo copia dentro alla
variabile di istanza heap[] (mettendoli dentro l'array Heap
a partire dalla posizione 1) e su di esso richiama ilmetodo
di classe heapify per trasformarlo in loco in un heap */
public function __construct($arr=array()){
/* Scorre l'array ricevuto come parametro e lo copia nel'array heap
traslando gli elementi una posizione in avanti (per farli partire dalla
posizione 1 e non 0) */
foreach($arr as $chiave => $valore){
$heap[$chiave+1] = $arr[chiave]; // Copia gli elementi traslandoli
$heapSize ++; //Incrementa di 1 il numero elementi inseriti nell'heap
}
/* Invoca il metodo heapify sull'array partendo dalla prima posizione che
sarà trasformato in un HEAP */
$this->heap = $this->heapify($heap, 1);
}
/* Metodo che dato un qualsiasi array lo riarrangia trasformandolo in una
struttura dati HEAP memorizzata sempre nello stesso array di partenza */
private function heapify($heap, $nodo_i){
echo "heapify è stata chiamata<br />";
$sin = sinistro($nodo_i); // Posizione della radice del sottoalbero sinistro
/* CASO BASE: Se heap è vuoto ritorna al chiamante */
if(sinistro($nodo_i) > $this->$heapSize) return;
/* Altrimenti procedi ricorsivamente nel seguente modo */
else{
$sin = sinistro($nodo_i); // Posizione della radice del sottoalbero sinistro
$des = destro($nodo_i); // Posizione della radice del sottoalbero destro
$nodoCorrente = $sin;
heapify($heap, $nodoCorrente); // Chiama ricorsivamente sul sottoalbero sinistro
$nodoCorrente = $des;
heapify($heap, $nodoCorrente); // Chiama ricorsivamente sul sottoalbero destro
fixHeap($nodoCorrente, $heap);
}
}
/* Metodo che prende in input un quasi heap (cioè un heap con al più
un'anomalia) ed un indice nodo_i e restituisce un heap corretto */
private function fixHeap($nodo_i, $quasiHeap){
$sin; // Conterrà l'indice del figlio sinistro
$des; // Conterrà l'indice del figlio destro
$max; // Conterrà l'indice del figlio avente valore massimo
/* Se nodo_i è una foglia allora ritorna al chiamante (caso base)*/
if(sinistro($nodo_i) > $this->$heapSize) return;
/* Se nodo_i non è una foglia */
else{
$sin = sinistro($nodo_i); // Posizione del figlio sinistro
$des = destro($nodo_i); // Posizione del figli destro
/* Trova il massimo tra il figlio sinistro e destro di nodo_i */
if($quasiHeap[sin] >= $quasiHeap[$des]) $max = $sin;
else $max = $des;
/* Se il valore in posizione nodo_i è MINORE del valore del figlio
massimo */
if($quasiHeap[$nodo_i] < $quasiHeap[$max]){
$tmp = $quasiHeap[$nodo_i]; // Salva il valore in posizione i
/* Scambia il valore in posizione nodo_i con il valore in
posizione max */
$quasiHeap[$nodo_i] = $quasiHeap[max];
$quasiHeap[$max] = $tmp;
/* Invoca ricorsivamente il metodo fixHeap() passandogli come
parametro lo stesso array e la posizione max */
fixHeap($max, $quasiHeap);
}
}
}
/* Metodo che dato l'indice di un elemento dell'heap calcola l'indice del
suo figlio sinistro nell'heap */
private function sinistro($indicePadre){
$sin = $indicePadre*2; // Calcola l'indice del figlio sinistro
return $sin; // Ritorna il valore di sin al chiamante
}
/* Metodo che dato l'indice di un elemento dell'heap calcola l'indice del
suo figlio destro nell'heap */
private function destro($indicePadre){
$des = $indicePadre*2 + 1; // Calcola l'indice del figlio destro
return $padre; // Ritorna il valore di des al chiamante
}
/* Metodo che dato un elemento dell'heap calcolal'indice del padre */
private function padre($indiceNodo){
$padre = floor(i/2); // Calcola la parte intera
return $padre; // Ritorna al chiamante la posizione del padre
}
}
echo "Test HEAP <br \>\n";
$arr = array(70,10, 14, 18, 11, 27);
$myHeap = new Heap($arr);
?>
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Mmmm...
Codice PHP:
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Te l ho scritto nel codice! Mettendoci $this-> davanti !
Guarda sopra!
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Quote:
Codice:
if($this->sinistro($nodo_i) > $this->$heapSize) return; |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Mmmm l'errore è cambiato; la linea è sempre la stessa? Sicuro?
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Quote:
Codice:
if($this->sinistro($nodo_i) > $this->heapSize) return; Ora però ho un altro problema ancora che non sò proprio da cosa possa dipendere...nella classe ho inserito un altro metodo stampaHeap() che mi dovrebbe stampare il contenuto dell'array heap...ma non stampa nulla Questo è il codice completo: Codice:
<?php
/* Classe che implementa la struttura dati HEAP e la sua funzionalità per
l'ordinamento di una collezione mediante l'algoritmo di ordinamento
Heap Sort */
class Heap{
/* Variabile di istanza che implementa la struttura dati ad albero
dell'heap per mezzo di un array */
private $heap = array();
private $heapSize = 0; // Numero di elementi correntemente dentro l'HEAP
/* Costruttore: Crea un nuovo oggetto istanza di Heap. Riceve un qualunque
array come parametro di input, lo copia dentro alla
variabile di istanza heap[] (mettendoli dentro l'array Heap
a partire dalla posizione 1) e su di esso richiama ilmetodo
di classe heapify per trasformarlo in loco in un heap */
public function __construct($arr=array()){
/* Scorre l'array ricevuto come parametro e lo copia nel'array heap
traslando gli elementi una posizione in avanti (per farli partire dalla
posizione 1 e non 0) */
foreach($arr as $chiave => $valore){
$heap[$chiave+1] = $arr[chiave]; // Copia gli elementi traslandoli
$heapSize ++; //Incrementa di 1 il numero elementi inseriti nell'heap
}
/* Invoca il metodo heapify sull'array partendo dalla prima posizione che
sarà trasformato in un HEAP */
$this->heap = $this->heapify($heap, 1);
}
/* Metodo che dato un qualsiasi array lo riarrangia trasformandolo in una
struttura dati HEAP memorizzata sempre nello stesso array di partenza */
private function heapify($heap, $nodo_i){
echo "heapify è stata chiamata<br />";
/* CASO BASE: Se heap è vuoto ritorna al chiamante */
if($this->sinistro($nodo_i) > $this->heapSize) return;
/* Altrimenti procedi ricorsivamente nel seguente modo */
else{
$sin = sinistro($nodo_i); // Posizione della radice del sottoalbero sinistro
$des = destro($nodo_i); // Posizione della radice del sottoalbero destro
$nodoCorrente = $sin;
heapify($heap, $nodoCorrente); // Chiama ricorsivamente sul sottoalbero sinistro
$nodoCorrente = $des;
heapify($heap, $nodoCorrente); // Chiama ricorsivamente sul sottoalbero destro
fixHeap($nodoCorrente, $heap);
}
}
/* Metodo che prende in input un quasi heap (cioè un heap con al più
un'anomalia) ed un indice nodo_i e restituisce un heap corretto */
private function fixHeap($nodo_i, $quasiHeap){
$sin; // Conterrà l'indice del figlio sinistro
$des; // Conterrà l'indice del figlio destro
$max; // Conterrà l'indice del figlio avente valore massimo
/* Se nodo_i è una foglia allora ritorna al chiamante (caso base)*/
if(sinistro($nodo_i) > $this->$heapSize) return;
/* Se nodo_i non è una foglia */
else{
$sin = sinistro($nodo_i); // Posizione del figlio sinistro
$des = destro($nodo_i); // Posizione del figli destro
/* Trova il massimo tra il figlio sinistro e destro di nodo_i */
if($quasiHeap[sin] >= $quasiHeap[$des]) $max = $sin;
else $max = $des;
/* Se il valore in posizione nodo_i è MINORE del valore del figlio
massimo */
if($quasiHeap[$nodo_i] < $quasiHeap[$max]){
$tmp = $quasiHeap[$nodo_i]; // Salva il valore in posizione i
/* Scambia il valore in posizione nodo_i con il valore in
posizione max */
$quasiHeap[$nodo_i] = $quasiHeap[max];
$quasiHeap[$max] = $tmp;
/* Invoca ricorsivamente il metodo fixHeap() passandogli come
parametro lo stesso array e la posizione max */
fixHeap($max, $quasiHeap);
}
}
}
/* Metodo che dato l'indice di un elemento dell'heap calcola l'indice del
suo figlio sinistro nell'heap */
private function sinistro($indicePadre){
$sin = $indicePadre*2; // Calcola l'indice del figlio sinistro
return $sin; // Ritorna il valore di sin al chiamante
}
/* Metodo che dato l'indice di un elemento dell'heap calcola l'indice del
suo figlio destro nell'heap */
private function destro($indicePadre){
$des = $indicePadre*2 + 1; // Calcola l'indice del figlio destro
return $padre; // Ritorna il valore di des al chiamante
}
/* Metodo che dato un elemento dell'heap calcolal'indice del padre */
private function padre($indiceNodo){
$padre = floor(i/2); // Calcola la parte intera
return $padre; // Ritorna al chiamante la posizione del padre
}
/* Metodo per stampare l'heap */
public function stampaHeap(){
for($i=1; $i<=$heapSize; $i++)
echo $heap[i];
}
}
echo "Test HEAP <br \>\n";
$arr = array(70,10, 14, 18, 11, 27);
$myHeap = new Heap($arr);
$myHeap->stampaHeap();
?>
|
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Non mi convince il passaggio di parametri...
la variabile $heap, se privata, come fa a prendersela il metodo di stampa? Dovrai passargliela come parametro no?
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Quote:
La mia variabile heap è privata, quindi è visibile solo nella classe. Se io dichiaro un metodo PUBLICO interno alla classe che stampa heap questo dovrebbe funzionare da interfaccia tra l'utente che usa la classe ed il contenuto della classe che è privato...per fare information hiding e nascondere l'implementazione della classe. Se io dichiaro privata la variabile heap è perchè non voglio far sapere all'utente che usa la classe come l'ho implementata...e gli fornisco un metodo stampa() d'interfaccia... O sbaglio qualcosa? Grazie |
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Quote:
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Quote:
Cmq credo che ci sia proprio un problema a livello semantico...ho provato anche ad inserire un echo $heap[1]; alla fine del costruttore...e non viene visualizzato nulla...è come se l'array heap fosse vuoto...doh Ultima modifica di e-commerce84 : 07-11-2009 alle 18:59. |
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Quote:
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Quote:
Le variabili globali sono variabili che possono venire usate da tutte le procedure e dal programma principale. Si tratta di variabili che sono definite al di fuori delle procedure, e che sono accessibili da tutti i blocchi del programma.
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Quote:
Intendi così: private global $heap = array(); Però mi da il seguente errore: Parse error: parse error, expecting `T_VARIABLE' in C:\xampp\htdocs\PHPEsempi\algoritmiOrdinamento\Heap.php on line 11 Che intendi esattamente? |
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Quote:
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Quote:
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Si ma cmq non credo dipenda da quello...in Java ho fatto varie cose analoghe...almeno così mi sembra di ricordare...
L'altra cosa che mi fa sospettare che non dipenda da quello è il fatto che se provo a far visualizzare (come test) ad esempio il primo elemento dell'array heap alla fine del costruttore non mi visualizza nulla...quindi mi viene il sospetto che per qualche motivo non popoli proprio l'array heap Mi servirebbe un debbugger che mi fa vedere passo passo cosa succede...ne esistono? |
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Apr 2008
Città: Varese
Messaggi: 406
|
Quote:
__________________
IT Developer at Hardware Upgrade S.r.l. self.love(this.me()); |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 01:09.



















