Ricorsione Ordinamento

di il
12 risposte

Ricorsione Ordinamento

Salve devo creare un metodo ricorsivo, che sfrutta la teoria del DIVIDE ET IMPERA, per controllare che un'array sia ordinato in modo crescente nell'intervallo di posizioni scelte dall'utente.
Io ho scritto questo codice ma mi da degli errori con Array molto lunghi in particolare questo tipo di errore: Exception in thread "main" java.lang.StackOverflowError

Di seguito riporto il codice da me scritto, vi ringrazio in anticipo.

public class MainClass {

public static void main(String[] args) {
// TODO Auto-generated method stub

int[] a = {1,14,31,34,56,65,69};
System.out.print(isOrdered(a,0,5));
}
static boolean isOrdered (int[] a, int inizio, int fine)
{
if(a==null) return true;
if(inizio==fine) return true; //caso base
if(a[inizio]<a[fine])
{
int m = (inizio+fine/2);
isOrdered(a,inizio,m);
isOrdered(a,m+1,fine);
return true;
}
else {return false;}
}
}

12 Risposte

  • Re: Ricorsione Ordinamento

    Beh sicuramente col tyuo algoritmo fai un ciclo infinito che ovviamente sfora in uno StackOverflowError
  • Re: Ricorsione Ordinamento

    Capito. Come potrei risolverlo?
  • Re: Ricorsione Ordinamento

    Il problema del loop infinito è nella precedenza degli operatori!
    L'operazione (inizio+fine/2) è equivalente a inizio + (fine/2), mentre quello che dovresti fare è (inizio+fine)/2.

    In ogni caso l'algoritmo è errato, cioè se passi in input l'array {1,32,31,34,56,65,69} viene restituito true.
  • Re: Ricorsione Ordinamento

    Grazie però ora quando verifica l'ordinamento mi restituisce true anche se è decrescente
  • Re: Ricorsione Ordinamento

    Grazie però ora quando verifica l'ordinamento mi restituisce true anche se è decrescente
  • Re: Ricorsione Ordinamento

    Eh si, l'algoritmo è errato. Così ad occhio ci sono diversi errori, in particolare non si confrontano mai i numeri m ed m+1, inoltre un array è ordinato se entrambe le sue metà lo sono, per cui quel return true è errato.


    Sent from my iPhone using Tapatalk
  • Re: Ricorsione Ordinamento

    Scusa come mai non si confrontano mai? Dov'è che sbaglio?
  • Re: Ricorsione Ordinamento

    Dunque, supponi di avere l'array {1,9,8,2}.
    All'inizio chiami isOrdered(array, 0, 3) [fra l'altro nota che in realtà all'inizio dovresti chiamare isOrdered(a, 0, a.length-1), non quello che chiami tu, perché ti perdi un numero].
    In ogni caso hai che array[0] < array[3], per cui calcoli m=1 e chiami isOrdered(array, 0, 1) e isOrdered(array, 2, 3). Concentriamoci solo sulla prima: hai che arrray[0] > array[1], quindi questa funzione restituisce false. Però per come è implementato attualmente te ne freghi di questo valore, che invece ti dice "ehi guarda, il sotto-array che va dall'indice 0 ad 1 non è ordinato". Di conseguenza il programma stampa sempre "true" anche se magari si accorge che un sotto-array non è ordinato.
    Per cui dovresti avere una cosa del tipo
    
    return isOrdered(a, inizio, m) && isOrdered(a, m+1, fine);
    
    Poi passiamo alla questione dei confronti fra array[m] e array[m+1].
    Considera l'array {1,2,8,4}.
    Come prima la sequenza di chiamate sarà:
    • isOrdered(array, 0, 3), cioè confronti array[0] con array[3]
    • isOrdered(array, 0, 1), isOrdered(array, 2,3). Cioè confronti array[0] con array[1] e, successivamente, array[2] con array[3]
    • isOrdered(array, 0, 0), isOrdered(array, 1, 1), isOrdered(array, 2, 2), isOrdered(array, 3, 3). Qua non effettui nessun confronto.
    Come puoi vedere non effettui mai il confronto array[1] con array[2], che è proprio quello che ti permetterebbe di dire che l'array non è ordinato. Di conseguenza il tuo programma in alcuni casi restituisce true invece di false.
  • Re: Ricorsione Ordinamento

    Ragazzi stesso problema, ecco la mia risoluzione. E' giusta?
    
    public class Mainclass {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		int[] a = {10,15,30,28};
    		System.out.print(isOrdered(a,0,3));
    	}
    	
    	
    	static boolean isOrdered (int[] a, int inizio, int fine){
    		if (inizio==fine || a==null) {return true;}
    		if (a[inizio]<=a[fine]) {
    			int m=(inizio+fine)/2;
    			return isOrdered (a, inizio, m) && isOrdered (a, m+1, fine);
    		}
    		else return false;
    }
    }
    
    
  • Re: Ricorsione Ordinamento

    Beh dimostrare che un programma è giusto non è particolarmente semplice, è più facile dire se è sbagliato, quindi fai un po' di test con array diversi e vedi cosa ti dice il programma. Comunque ad occhio mi pare identico al codice visto prima, quindi direi proprio che non va bene!


    Sent from my iPhone using Tapatalk
  • Re: Ricorsione Ordinamento

    Si in certi casi non funziona , voi come lo avreste risolto?
    E' proprio sbagliato questo modo di risolverlo ?
  • Re: Ricorsione Ordinamento

    Ma l'array bisogna passarlo dal codice oppure dalla console?Cioè una volta scelta la lunghezza dell'array lo riempiamo noi o ne creiamo uno predefinito all'inizio?
Devi accedere o registrarti per scrivere nel forum
12 risposte