Capitolo 11
Ricorsione
Lucidi relativi al volume:
Java – Guida alla programmazione
James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Definizioni ricorsive
 Una definizione che definisce qualcosa in base a sé stessa è
chiamata definizione ricorsiva.
 I discendenti di una persona sono i figli della persona e
tutti i discendenti dei figli della persona.
 Un elenco di numeri è un numero o un numero seguita da
una virgola e un elenco di numeri.
 Un algoritmo ricorsivo è un algoritmo che invoca sé stesso
per risolvere istanze più piccole o più semplici di un
problema.
 Il fattoriale di un numero n è n volte il fattoriale di n-1.
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Fattoriale
 Una definizione imprecisa
1
n!  
n  (n  1) 
n0
1 n  1
 Una definizione precisa
n0
1
n!  
n  (n -1)! n  1
I puntini di sospensione
comunicano al lettore di
utilizzare l'intuizione per
riconoscere lo schema
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Metodi ricorsivi
 Un metodo ricorsivo possiede generalmente due parti.
 Una parte di terminazione che ferma la ricorsione.
 È chiamata caso di base.
 Il caso di base deve avere una soluzione semplice o
banale.
 Una o più chiamate ricorsive.
 È chiamato caso ricorsivo.
 Il caso ricorsivo chiama lo stesso metodo ma con
argomenti più semplici o più piccoli.
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Method factorial()
public static int factorial(n) {
if (n == 0) {
Caso di base
return 1;
}
else{
return n * factorial(n-1);
}
}
Il caso ricorsivo gestisce una versione
più semplice (piccola) dell'attività
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Method factorial()
public static int factorial(n) {
if (n == 0) {
return 1;
}
else{
return n * factorial(n-1);
}
}
public static void main(String[] args){
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
int n = Integer.parseInt(stdin.readLine());
int nfactorial = factorial(n);
System.out.println(n + “! = “ + nfactorial;
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
factorial()
int
n = 3
nfactorial
return
n
*
=
factorial(n);
factorial(n-1);
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return
n
*
factorial(n-1);
factorial()
n = 2
return
n
*
factorial(n-1);
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return
n
*
factorial(n-1);
factorial()
n = 2
return
n
*
factorial(n-1);
factorial()
n = 1
return
n
*
factorial(n-1);
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return
n
*
factorial(n-1);
factorial()
n = 2
return
n
*
factorial(n-1);
factorial()
n = 1
return
n
*
factorial(n-1);
factorial()
n = 0
return
1;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return
n
*
factorial(n-1);
factorial()
n = 2
return
n
*
factorial(n-1);
factorial()
n = 1
return
n
*
factorial(n-1);
factorial()
n = 0
return
1;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return
n
*
factorial(n-1);
factorial()
n = 2
return
n
*
factorial(n-1);
factorial()
n = 1
factorial()
n = 0
return n * 1;
return
1;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return
n
*
factorial(n-1);
factorial()
n = 2
return
n
*
factorial(n-1);
factorial()
n = 1
return 1 * 1;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
factorial()
n = 2
return n * 1
factorial()
n = 1
return 1 * 1;
return
n
*
factorial(n-1);
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
factorial()
n = 3
factorial()
n = 2
nfactorial
return
n
*
=
factorial(n);
factorial(n-1);
return 2 * 1
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int
nfactorial
=
factorial(n);
factorial()
n = 3
return n * 2;
factorial()
n = 2
return 2 * 1;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
factorial()
int
n = 3
nfactorial
=
factorial(n);
return 3 * 2;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
factorial()
int nfactorial = 6;
n = 3
return 3 * 2;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Invocazione ricorsiva
 Un nuovo record di attivazione viene creato per ogni
invocazione del metodo
 Comprese le invocazioni ricorsive
main()
int nfactorial = 6;
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Numeri di Fibonacci
 Sviluppati da Leonardo Pisano nel 1202.
 Analisi della velocità con cui i conigli possono figliare in
circostanze ideali.
 Supposizioni
 Una coppia di conigli maschio e femmina figlia sempre
e produce un'altra coppia di conigli maschio e
femmina.
 Un coniglio diventa sessualmente maturo dopo un
mese; anche il periodo di gestazione è pari a un mese.
 Pisano voleva conoscere la risposta alla domanda: quanti
conigli esisteranno dopo un anno?
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Numeri di Fibonacci
 La sequenza generata è: 1, 1, 2, 3, 5, 8, 13, 21, 34, …
 Il numero di coppie per un mese è uguale alla somma del
numero di coppie nei due mesi precedenti.
 Inserimento dell'equazione di Fibonacci
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Numeri di Fibonacci
 Pattern del metodo ricorsivo
if ( codice di terminazione soddisfatto ) {
return value;
}
else{
esegui chiamata ricorsiva più semplice;
}
public static int fibonacci(int n) {
if (n <= 2) {
return 1;
}
else{
return fibonacci(n-1) + fibonacci(n-2);
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Numeri di Fibonacci
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Ricorsione infinita
 Un errore di programmazione comune
nell'utilizzo della ricorsione è non terminare
le chiamate ricorsive.
 Il programma continuerà la ricorsione fino a esaurimento
della memoria.
 Occorre assicurarsi che le chiamate ricorsive siano
eseguite su sottoproblemi più semplici o piccoli, e che
l'algoritmo abbia un caso di base che termini la ricorsione.
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Ricerca binaria



Confrontare la voce con l'elemento centrale dell'elenco. Se la voce
corrisponde all'elemento centrale, la voce desiderata è stata
individuata e la ricerca termina.
Se la voce non corrisponde, allora se la voce è nell'elenco deve
trovarsi a sinistra o a destra dell'elemento centrale.
L'elenco secondario corretto può essere ricercato utilizzando la
stessa strategia.
0
1
2
3
4
5
6
10
24
33
45
56
81
95
entryquesto
to this element.
If the
matches, the la ricerca è
ConfrontareCompare
la voce con
elemento.
Seentry
corrispondono,
If thesignifica
entry is less
45,
then the in elenco,
finita. Se lasearch
voce is
è successful.
minore di 45,
che,than
se è
presente
entry, if ait sinistra
is in the list,
must be to the
left in elements
0-2.
può solo trovarsi
dell'elemento
centrale,
ossia compresa
tra 0
If the
entry èis più
greater
thandi
45,45,
then
thesolo
entry,
if it is inathe
e 2. Se
invece
grande
può
trovarsi
destra
list, mustcentrale,
be to the ossia
right incompresa
elements 4-6.
dell'elemento
tra 4 e 6.
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Sviluppo della ricerca per una rubrica
public class AddressEntry {
private String personName;
private String telephoneNumber;
public AddressEntry(String name, String number) {
personName = name;
telephoneNumber = number;
}
public String getName() {
return personName;
}
public String getNumber() {
return telephoneNumber;
}
public void setName(String Name) {
personName = Name;
}
public void setTelephoneNumber(String number) {
telephoneNumber = number;
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Ricerca binaria

Interfaccia pubblica
 Dovrebbe essere il più semplice possibile
 Nessun parametro estraneo
public static AddressEntry recSearch(AddressEntry[]
addressBook, String name)

Interfaccia privata
 Invocata dall'implementazione dell'interfaccia pubblica
 Dovrebbe supportare l'invocazione ricorsiva per
implementazione dell'interfaccia privata
private static AddressEntry recSearch(AddressEntry[]
addressBook, String name, int first, int last)
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Ricerca binaria

Implementazione dell'interfaccia pubblica
public static AddressEntry recSearch(AddressEntry[]
addressBook, String name) {
return recSearch(addressBook, name, 0,
addressBook.length-1);
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Implementazione dell'interfaccia privata
static AddressEntry recSearch(AddressEntry[] addressBook,
String name, int first, int last) {
// caso di base: se la sezione dell'array è vuota
l'elemento non è stato trovato
if (first > last)
return null;
else{
int mid = (first + last) / 2;
// se il valore è stato trovato la ricerca termina
if (name.equalsIgnoreCase(addressBook[mid].getName()))
return addressBook[mid];
else if (name.compareToIgnoreCase(
addressBook[mid].getName()) < 0) {
// se il valore è presente è nella metà sinistra
return recSearch(addressBook, name, first, mid-1);
}
else // array[mid] < value
// se il valore è presente è nella metà destra
return recSearch(addressBook, name, mid+1, last);
}
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Verifica
 Sviluppare casi di verifica per provare
ogni possibile situazione univoca
public static void main(String[] args){
// l'elenco deve essere ordinato
AddressEntry addressBook[] = {
new AddressEntry("Audrey", "434-555-1215"),
new AddressEntry("Emily" , "434-555-1216"),
new AddressEntry("Jack" , "434-555-1217"),
new AddressEntry("Jim"
, "434-555-2566"),
new AddressEntry("John" , "434-555-2222"),
new AddressEntry("Lisa" , "434-555-3415"),
new AddressEntry("Tom"
, "630-555-2121"),
new AddressEntry("Zach" , "434-555-1218")
};
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Verifica

Ricerca del primo elemento
AddressEntry p;
// primo elemento
p = recSearch(addressBook, "Audrey");
if (p != null) {
System.out.println("Audrey's telephone number is " +
p.getNumber());
}
else{
System.out.println("No entry for Audrey");
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Verifica

Ricerca dell'elemento centrale
p = recSearch(addressBook, "Jim");
if (p != null) {
System.out.println("Jim's telephone number is " +
p.getNumber());
}
else{
System.out.println("No entry for Jim");
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Verifica

Ricerca dell'ultimo elemento
p = recSearch(addressBook, "Zach");
if (p != null) {
System.out.println("Zach's telephone number is " +
p.getNumber());
}
else{
System.out.println("No entry for Zach");
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Verifica

Ricerca di un elemento inesistente
p = recSearch(addressBook, "Frank");
if (p != null) {
System.out.println("Frank's telephone number is " +
p.getNumber());
}
else{
System.out.println("No entry for Frank");
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Efficienza della ricerca binaria





L'altezza di una struttura binaria è il
numero massimo di confronti necessari per
la ricerca in un elenco
Una struttura con 31 nodi ha altezza 5
In generale, una struttura con n nodi ha
un altezza pari a log2(n+1)
La ricerca in un elenco con un miliardo di
nodi richiede solo 31 confronti
La ricerca binaria è efficiente!
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
 Mergesort è un ordinamento ricorsivo che divide
concettualmente il suo elenco di n elementi da ordinare in
due elenchi secondari di dimensione n/2.
 Se un elenco secondario contiene più di un elemento,
l'elenco secondario viene ordinato con una chiamata
ricorsiva a mergeSort().
 Dopo che i due elenchi secondari di dimensione n/2 sono
ordinati, vengono uniti per produrre un singolo elenco
ordinato di dimensione n.
 Questo tipo di strategia è detta dividi e conquista: il problema
è diviso in sottoproblemi di complessità minore e le soluzioni
dei sottoproblemi sono utilizzate per produrre la soluzione
generale.
 Il tempo di esecuzione del metodo mergeSort() è
proporzionale a n log n.
 Questa prestazione è a volte detta prestazione linearitmica.
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort

Si supponga di voler ordinare
l'array mostrato.
'Q' 'W' 'E' 'R' 'T' 'Y' 'U' 'I' 'O' 'P'
 Dopo l'ordinamento dei due elenchi secondari, l'array sarà:
'E' 'Q' 'R' 'T' 'W' 'I' 'O' 'P' 'U' 'Y'
Left sorted sublist
Right sorted sublist
 Ora è possibile svolgere l'attività di unione dei due array per
ottenere:
'E' 'I' 'O' 'P' 'Q' 'R' 'T' 'U' 'W' 'Y'
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort

Interfaccia pubblica
 Dovrebbe essere il più semplice possibile
 Nessun parametro estraneo
public static void mergeSort(char[] a)

Interfaccia privata
 Invocata dall'implementazione dell'interfaccia
pubblica
 Dovrebbe supportare l'invocazione ricorsiva per
implementazione dell'interfaccia privata
private static void mergeSort(char[] a, int left, int
right)
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
private static void
mergeSort(char[] a, int left, int right) {
if (left < right) {
// esistono più elementi da ordinare.
// per prima cosa, ordina in modo ricorsivo gli
elenchi secondari
int mid = (left + right)/2;
mergeSort(a, left, mid);
mergeSort(a, mid+1, right);
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
// poi unisce gli elenchi secondari ordinati
// nell'array temp
char[] temp = new char[right - left + 1];
int j = left;// indice dell'elemento più piccolo a sinistra
int k = mid + 1;// indice dell'elemento più piccolo a destra
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
for (int i = 0; i < temp.length; ++i) {
// memorizza l'elemento più piccolo in temp
if ((j <= mid) && (k <= right)) {
// deve prendere il più piccolo tra a[j]
// e a[k]
if (a[j] <= a[k]) // sinistra contiene l'elemento più
piccolo
temp[i] = a[j];
++j;
}
else // destra contiene l'elemento più piccolo
temp[i] = a[k];
++k;
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
else if (j <= mid) // può prendere solo da sinistra
temp[i] = a[j];
++j;
}
else // può prendere solo da destra
temp[i] = a[k];
++k;
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
// infine copia temp in a
for (int i = 0; i < temp.length; ++i) {
a[left + i] = temp[i];
}
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Mergesort
L'invocazione considera gli elementi di
EQRTWYUIOP con indici compresi
nell'intervallo da 5 a 9 e produce
EQRTWIOPUY
L'invocazione iniziale considera
gli elementi di QWERTYUIOP
nell'intervallo da 0 a 9 e
produce EIOPQRTUWY
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Ricorsione e iterazione
 L'iterazione può essere più efficiente
 Sostituisce le chiamate ai metodi con i cicli
 Viene utilizzata meno memoria (nessun record di
attivazione per ogni chiamata)
 Molti problemi sono risolti più naturalmente con la ricorsione
 Torri di Hanoi
 Mergesort
 La scelta dipende dal problema e dal contesto della soluzione
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Confusione giornaliera
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Confusione giornaliera
 Attività
 Genera tutte le possibili permutazioni delle lettere
 Per n lettere ci sono n! possibilità
 n scelte per la prima lettera
 n-1 scelte per la seconda lettera
 n-2 scelte per la terza lettera
 …
 Iteratore
 Oggetto che produce valori successivi in una sequenza
 Progettazione
 Classe iteratore PermuteString che supporta
l'enumerazione delle permutazioni
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Classe PermuteString
 Costruttore
public PermuteString(String s)
 Costruisce un generatore di permutazioni per la stringa
s
 Metodi
public String nextPermutation()
 Restituisce la successiva permutazione della stringa
associata
public boolean morePermutations()
 Indica se esiste una permutazione non enumerata della
stringa associata
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Classe PermuteString
 Variabili istanza
private String word
 Rappresenta la parola da permutare
private int index
 Posizione all'interno della parola su cui operare
public PermuteString substringGenerator
 Generatore di sottostringhe
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Costruttore
public PermuteString(String s){
word = s;
index = 0;
if (s.length() > 1) {
String substring = s.substring(1);
substringGenerator = new PermuteString(substring);
}
else{
substringGenerator = null;
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Considerare
 Cosa accade?
PermuteString p = new PermuteString(“ath“);
p
word: "ath"
index: 0
substringGenerator:
word: "th"
index: 0
substringGenerator:
word: "h"
index: 0
substringGenerator:
null
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Metodo
public boolean morePermuations() {
return index < word.length;
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Metodo
public boolean nextPermutation() {
if (word.length() == 1) {
++index;
return word;
}
else{
String r = word.charAt(index)
+ substringGenerator.nextPermutation();
if (!substringGenerator.morePermutations()) {
++index;
if (index < word.length()) {
String tail = word.substring(0, index)
+ word.substring(index + 1);
substringGenerator = new permuteString(tail);
}
}
return r;
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Confusione giornaliera