2015-01-27 12 views
5

Sto passando per il capitolo 3 in eloquente javascript e la ricorsione è stata appena introdotta e sto cercando di avvolgere la mia mente su questo concetto.Puoi spiegare questa soluzione ricorsiva dal Cap 3 Eloquent js?

Inoltre, qualcuno può spiegare la cronologia del secondo parametro nella funzione Trova?

La cronologia è già stata definita?

Considerate questo puzzle: partendo dal numero 1 e ripetutamente aggiungendo 5 o moltiplicando per 3, è possibile produrre una quantità infinita di nuovi numeri. Come scriveresti una funzione che, dato un numero, cerca di trovare una sequenza di tali aggiunte e moltiplicazioni che producono quel numero? Ad esempio, il numero 13 potrebbe essere raggiunto prima moltiplicando per 3 e quindi aggiungendo 5 due volte, mentre il numero 15 non può essere raggiunto affatto.

function findSolution(target) { 
    function find(start, history) { 
    if (start == target) 
     return history; 
    else if (start > target) 
     return null; 
    else 
     return find(start + 5, "(" + history + " + 5)") || 
      find(start * 3, "(" + history + " * 3)"); 
    } 
    return find(1, "1"); 
} 

console.log(findSolution(24)); 
+0

Tenete a mente, 'history' è j con una stringa, niente di più. – Nit

+1

in questi casi, trovo che un console.log() o due possono davvero chiarire le cose. – dandavis

risposta

0

Storia è specificato quando la funzione viene chiamata find. Non è possibile chiamare la funzione find senza fornire un valore per la cronologia. Ricorda che la funzione non verrà eseguita fino a quando non viene chiamata, quindi la cronologia non ottiene un valore finché non viene indicato il suo valore è "1" sulla riga return find(1, "1"); La cronologia delle variabili viene definita dall'essere la cosa dopo la virgola quando viene chiamato lo find.

0

Ahh, mi ricordo di sbattere la testa contro questo per molto tempo ...

L'autore sta definendo la funzione find all'interno della funzione findSolution, che è piuttosto confusa

Se riscrivo in questo modo, lo otterrete:

function find(start, history) { 
    if (start == target) 
     return history; 
    else if (start > target) 
     return null; 
    else 
     return find(start + 5, "(" + history + " + 5)") || 
      find(start * 3, "(" + history + " * 3)"); 
} 

function findSolution(target) { 
    return find(1, "1"); 
} 

console.log(findSolution(24)); 
3

console.log stamperà il valore restituito da findSolution (24) dove 24 è il target.

ora, quando viene eseguita la funzione findSolution(), richiama (chiama) la funzione "trova" con 2 parametri: start = 1, history = "1" quindi restituisce qualcosa da stampare.

"return" restituisce al luogo in cui è stata impostata la chiamata. il significato find() viene chiamato all'interno di findSolution(), quindi return restituirà un valore in cui è stato chiamato all'interno di findSolution.

nel nostro caso:

se inizio === bersaglio

return history //(to findSolution. let's call it "H") 
return H to console.log() // prints 1 

altrimenti se inizio> Target

return null //(to findSolution, let's call it N) 
return N to console.log() // prints null 

altrimenti se inizio è minore rispetto a bersaglio, ritorno A || B

A = find(start + 5, "(" + history + " + 5)") 
B = find (start * 3, "(" + history + " * 3)") 

significato ritorno A se A è verità altrimenti restituisce B; A o B vengono valutati prima che la funzione ritorni.

andiamo attraverso un passo alla volta:

scoperta verrà richiamato di nuovo e di nuovo con parametro start incrementato di 5 cioè:

return find(1, "1") // start = 1, history = "(1 + 5)"  
return find(6, history) // start = 6, history = "(1 + 5) + 5" 
return find(11, history) // start = 11, history = "(1 + 5) + 5) + 5" 
return find(16, history) // start = 16, history = "(1 + 5) + 5) + 5) + 5" 
return find(21, history) start = 21, history = "(1 + 5) + 5) + 5) + 5) + 5" 

ora il valore successivo sarà 26. da 26> 22, "trova" restituirà B invece

return find(63, history) start = 21 * 3 = 63,  
//since 63 > 24, "null" is returned where start = 16,  

start è 16 e non 63 perché è un parametro. Non è cambiato e non sa nulla dell'incremento di 5 che si è verificato durante l'invocazione.

find (21 * 3, storia), 48> 24 quindi ritorna null dove start = 11
find (11 * 3, storia), 33> 24 così tornare nullo dove start = 6
find (6 * 3, cronologia), start = 18 e 18 < 24 quindi A sarà true start verrà incrementato di 5
return find (18 + 5, history)
return find (23 + 5, history) 28> 24, A è null, B viene valutata

... e così via e così via fino a inizio è uguale 24

Problemi correlati