Silvia Rossi. Algoritmi di Ricerca. Informatica. Lezione n. Parole chiave: Ricerca Lineare Ricerca Binaria. Corso di Laurea:

Documenti analoghi
ESERCIZIO 1 (Definizione funzioni passaggio parametri per copia)

Ricerca sequenziale di un elemento in un vettore

4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste

Matematica - SMID : Programmazione Febbraio 2009 FOGLIO RISPOSTE

Vettori Algoritmi elementari di ordinamento

Gestione di files Motivazioni

Codifica: dal diagramma a blocchi al linguaggio C++

Algoritmi di Ricerca. Esempi di programmi Java

PIANO DI LAVORO. a.s / 2016

Prova Scritta del 19/07/10

ESERCIZI DI PROGRAMMAZIONE C/C++ per le classi terza

Sistemi Web per il turismo - lezione 3 -

Le stringhe. Le stringhe

La selezione binaria

void funzioneprova() { int x=2; cout<<"dentro la funzione x="<<x<<endl; }

VBA è un linguaggio di scripting derivato da Visual Basic, da cui prende il nome. Come ogni linguaggio ha le sue regole.

Algoritmi su array / 2

PROGRAMMA DI SCIENZE E TECNOLOGIE APPLICATE 2015/2016 Classe 2ª Sez. C Tecnologico

Ricerche, ordinamenti e fusioni. 5.1 Introduzione. 5.2 Ricerca completa

Corso di Fondamenti di Informatica Algoritmi su array / 2

Informatica B. Sezione D. Scuola di Ingegneria Industriale Laurea in Ingegneria Energetica Laurea in Ingegneria Meccanica

Bontà dei dati in ingresso

1: /* Nome del programma: gestione_articoli_01.cpp 2: Realizzato da: Gaetano Della Cerra 3: Data: 06/02/ III Informatica Serale I.T.I.S.

L algoritmo di ricerca binaria. Daniele Varin LS Ing. Informatica Corso di Informatica teorica Docente: prof. Paolo Sipala

Laurea triennale - Comunicazione&DAMS - UNICAL. Dr. Marco Manna 1

Programmazione I / Informatica generale Prova scritta 11 Giugno 2008

Semplici Algoritmi di Ordinamento

IL CONCETTO DI FILE. È illecito operare oltre la fine del file.

Preparati per il compito in classe Modulo 5

Appunti del corso di Informatica 1 (IN110 Fondamenti) 6 Introduzione al linguaggio C

Riconoscere e formalizzare le dipendenze funzionali

Note su quicksort per ASD (DRAFT)

Università degli Studi di Cassino Corso di Fondamenti di Informatica Puntatori. Anno Accademico 2010/2011 Francesco Tortorella

10 - Programmare con gli Array

3. La sintassi di Java

RICERCA DI UN ELEMENTO

Laboratorio di Programmazione Gruppo III, Ml-ZZ. Alberto Finzi

Appunti del corso di Informatica 1. 6 Introduzione al linguaggio C

Laboratorio di Algoritmi e Strutture Dati

Grammatica di base: Pointers

Programmazione Orientata agli Oggetti in Linguaggio Java

3. Terza esercitazione autoguidata: progetto gestione voli

Esame di Informatica Generale 9 CFU 21 Giugno 2011 Professori: Carulli, Fiorino, Mazzei

BOZZA. cin per la comunicazione dal dispositivo di input standard, la tastiera, al programma (stream di input standard)

PROBLEMA DELLA RICERCA DI UN ELEMENTO IN UN ARRAY E ALGORITMI RISOLUTIVI

Programmazione 1 A.A. 2015/2016

LICEO SCIENTIFICO "LEONARDO DA VINCI" - RC PROGRAMMA DI INFORMATICA A.S. 2014/15 - CLASSE: I Q - Indirizzo Scienze applicate Prof Miritello Rita

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Studente (Cognome Nome): Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Primo scritto 11 Gennaio 2008

FUNZIONI CONTINUE - ESERCIZI SVOLTI

Laboratorio di Programmazione 1. Docente: dr. Damiano Macedonio Lezione 18 31/03/2014

INFORMATICA - I puntatori Roberta Gerboni

Le Liste. Elisa Marengo. Università degli Studi di Torino Dipartimento di Informatica. Elisa Marengo (UNITO) Le Liste 1 / 31

Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Secondo Compitino 17 Dicembre 2005

Sottoprogrammi: astrazione procedurale

puntatori Lab. Calc. AA 2007/08 1

I file Laboratorio di Linguaggi di Programmazione a.a. 2001/2002

Traccia. Analisi di massima

3) Il seguente numerale A1F0 in base 16 a quale numero in base 10 corrisponde?

Fondamenti di Informatica 2

AA LA RICORSIONE

Linguaggio C - Funzioni

Esercitazione Informatica I AA Nicola Paoletti

RICORSIONE - schema ricorsivo (o induttivo) si esegue l'azione S, su un insieme di dati D, mediante eventuale esecuzione di

Appello di Informatica B

2. Spiegare brevemente qual è la funzione del compilatore e la sua importanza per il programmatore.

Progetto Lauree Scientifiche Liceo Classico L.Ariosto, Ferrara Dipartimento di Matematica Università di Ferrara 24 Gennaio 2012

ESAME SCRITTO DI ELEMENTI DI INFORMATICA E PROGRAMMAZIONE. 27 Gennaio 2015

Esonero del corso di Programmazione a Oggetti

Corso di Tecniche di Programmazione

Algoritmi di ordinamento

Files in C++ Fondamenti di Informatica. R. Basili. a.a

Esercitazione 7. Procedure e Funzioni

Verifica che una grammatica sia Context Free nel GrammaReader

Funzioni. Il modello console. Interfaccia in modalità console

Il programma OCTAVE per l insegnamento dell algebra lineare nella Scuola Secondaria p. 1

Modulo 5 La programazione Unità 4 Selezione

SARA DHANA. RELAZIONE NEGOZIO A.BASSI a.s.2013/2014

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Matematica con il foglio di calcolo

Algoritmi e Strutture Dati

Sistemi Operativi Anno Accademico 2011/2012. Segnali: Interrupt software per la gestione di eventi asincroni

Funzioni in C. Violetta Lonati

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a giugno 2013

Creare una funzione float square(float x). La funzione deve restituire il quadrato del parametro x.

1 introdurre le monete per l importo necessario. 2 selezionare la quantità di zucchero. 3 selezionare la bevanda desiderata

Università di Torino Facoltà di Scienze MFN Corso di Studi in Informatica. Programmazione I - corso B a.a prof.

1 Automi Cellulari (Rev )

Gli array. Gli array. Gli array. Classi di memorizzazione per array. Inizializzazione esplicita degli array. Array e puntatori

Gestione dinamica di una pila

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Informatica 3. LEZIONE 21: Ricerca su liste e tecniche di hashing. Modulo 1: Algoritmi sequenziali e basati su liste Modulo 2: Hashing

Due algoritmi di ordinamento. basati sulla tecnica Divide et Impera: Mergesort e Quicksort

Introduzione a Visual Basic Lezione 1 Concetti base e istruzioni condizionali

Liceo Marie Curie (Meda) Scientifico Classico Linguistico PROGRAMMAZIONE DISCIPLINARE PER COMPETENZE

Carta di credito standard. Carta di credito business. Esercitazione 12 maggio 2016

Laboratorio di Calcolatori 1 Corso di Laurea in Fisica A.A. 2006/2007

Programmazione I - Laboratorio

Prof. Giuseppe Chiumeo. Avete già studiato che qualsiasi algoritmo appropriato può essere scritto utilizzando soltanto tre strutture di base:

Transcript:

Silvia Rossi Algoritmi di Ricerca 22 Lezione n. Parole chiave: Ricerca Lineare Ricerca Binaria Corso di Laurea: Informatica Insegnamento: Programmazione I Email Docente: srossi@na.infn.it A.A. 2009-2010

Relazione di Equivalenza ugualglianza di valori: x == è vera se le varibili distinte x e y hanno valori uguali identità: &x == &y è vera se x e y sono nomi diversi di una stessa variabile (ad esempio passaggio per riferimento di parametri di una funzione) uguaglianza parziale di valori: supponendo che x e y siano variabili assegnate a oggetti (o record) C++, x e y possono essere equivalenti se alcuni attributi (campi) hanno lo stesso valore (ad esempio, record di un database con le stesse chiavi).

Ricerca in un vettore Problema della ricerca di un elemento in una sequenza (insieme)» una relazione di equivalenza (ad es. == in C++) Input: una sequenza A di n elementi a 1, a 2,..., a n un elemento x da ricercare in A Output: vero se esiste almeno un i tale che x» a i ; falso altrimenti Per rappresentare in C++ sequenze di elementi usiamo I vettori a[0], a[1],..., a[n-1] Esempio: consideriamo come relazione di equivalenza l operatore booleano == x=7; a[]={2, 4, 5, 7, 7, 9, 12}; b[]={2, 5, 8, 3, 0, 11}; (x==a[3] e x == a[4]) (non esiste i tale che x==a[i]) È un tipico esempio di algoritmo esiste

Ricerca lineare

i 0 trovato false while NOT trovato AND i < N if A[i]=x trovato true else i=i+1 if trovato return i else return -1 Ricerca lineare

Ricerca lineare Ricerca di un elemento in un vettore generico L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x = a[i]; altrimenti ritorna -1 i 0 1 2 4 5 6 7 9 10 12 13 x=7 i ß 0 trovato ß falso while ((not trovato) and i < n): if A[i] = x: trovato ß vero else: i ß i + 1 if trovato: indice ß i else: indice ß -1

Ricerca lineare Possiamo eliminare la variabile sentinella trovato in questo modo: Scorriamo il vettore con un ciclo while controllato da una espressione booleana che termina il ciclo o quando A[i] = x, oppure quando arriva alla fine del vettore i 0 while A[i]<>x AND i < N i=i+1 ; if A[i]=x return i else return -1 Ricerca lineare O(n)

L algoritmo di ricerca lineare può essere migliorato se si hanno delle informazioni opportune sul tipo di array da esaminare. Ad esempio l algoritmo di ricerca potrebbe essere migliorato se è noto che il vettore pur essendo disordinato presenta solo numeri negativi fino alla posizione k seguiti da valori non negativi. Infatti in questo caso se il numero da cercare non è negativo possiamo scartare i primi k+1 elementi. In altri termini ogni informazione che ci permette di scartare potenziali candidati è utile per migliorare la ricerca.

Cosa si può fare se il nostro array è ordinato? Si potrebbe adoperare una ricerca lineare modificata nel senso che o l algoritmo si arresta non appena trova l elemento in questione o si interrompe dando in uscita 1 non appena incontra un numero maggiore. i 0 while A[i]<x AND i < N i=i+1 ; if A[i]=x indice=i else indice=-1 Ricerca binaria Si avrebbe un certo miglioramento in media, ma nel caso peggiore occorre comunque esaminare tutto l array.

Ricerca di una parola in un dizionario Ricerca binaria

Che informazione otteniamo se confrontiamo il nostro x con un generico elemento di indice k? Se x=a[k] la ricerca è finita, se è maggiore allora possiamo scartare tutti i candidati da 0 fino a k, altrimenti scartiamo tutti quelli da k in poi. Conviene scegliere k=n/2, in tal modo un confronto fallito dimezza il numero di possibili candidati. Iterando questo procedimento con cui dimezziamo l indice e confrontiamo i valori, ad ogni fallimento i due estremi dell intervallo di ricerca che contiene i candidati ancora non scartati si avvicinano sempre di più. L algoritmo terminerà in una delle seguenti situazioni : a) uno dei confronti ha successo. b) gli estremi dell intervallo di ricerca danno un intervallo vuoto. Nel qual caso l elemento non è nell array.

basso 0 Alto N-1 i -1 while (basso<=alto)and (i=-1) Medio = (basso+alto) / 2 if else x = vet[medio] i=medio if else x>vet[medio] basso = Medio+1 Alto =Medio-1

Utilizzando l algoritmo, vogliamo verificare se 21 appartiene al vettore di interi: vet=[ 9, 10, 15, 18, 21, 29, 30, 35 ] di dimensione 8. 0 1 2 3 4 5 6 7 Nel nostro esempio x=21, basso=0 ed Alto=7. Inizialmente Medio=(0+7)/2=3, per cui, essendo vet[3]=18, si ha x > vet[medio] è vero analizziamo il sub-array superiore che va dall indice 4 fino ad Alto; per questo scopo basta porre basso=medio+1=4. Abbiamo basso=4, Alto =7 Medio=(4+7)/2=5 e vet[medio]=29. Dal confronto x > vet[medio] è falso scaturisce che dobbiamo analizzare il subarray Inferiore (da 4 a 4), per cui Alto=Medio-1=4; poiché basso=4, Alto=4 e Medio=(4+4)/2=4 si ottiene ancora x = vet[medio] restituisce l indice del valore cercato, i=4. basso 0 Alto N-1 i -1 while (basso<=alto)and (i=-1) Medio = (basso+alto) / 2 if x = vet[medio] i=medio else if x>vet[medio] basso = Medio+1 else Alto =Medio-1

Vogliamo sapere se 21 appartiene alla seguente lista vet=[ 9, 10, 15, 18, 21, 29, 30, 35 ] di dimensione 8. [0] 9 [1] [2] [3] [4] [5] [6] [7] 1 10 15 18 21 29 30 35 N N/2 0 2 [4] [5] [6] [7] 21 29 30 35 N/2 N/2 1 3 [4] 21 N/4 N/2 2 N O(N) LOG(N) 1.000 1.000 9,97 1.000.000 1.000.000 19,93 100.000.000 100.000.000 26,58 k=log 2 N 1 N/2 k

vet=[ 9, 10, 15, 18, 21, 29, 30, 35 ] 0 1 2 3 4 5 6 7 Analizziamo la ricerca con x=17. Scrivendo i vari passaggi in maniera più compatta, otteniamo basso Alto Medio x =vet[medio] x > vet[medio] 0 7 3 falso falso 0 2 1 falso vero 2 2 2 falso vero 3 2 poiché basso è maggiore di Alto non esiste più alcun intervallo di ricerca.

Ricerca di un elemento in un vettore generico ordinato L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x == A[i]; altrimenti ritorna -1 basso medio alto 0 1 2 4 5 6 7 basso ß 0 alto ß n -1 i ß -1 while (basso alto and i < 0): medio ß (basso + alto) / 2 if x = A[medio]: i ß medio else: if x > A[medio]: basso ß medio + 1 else: alto ß medio - 1 9 1012 13 15 16 18 20 21 23 24 26 28 x=16

Ricerca di un elemento in un vettore generico ordinato L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x == A[i]; altrimenti ritorna -1 basso 0 1 2 4 5 6 7 basso ß 0 alto ß n -1 i ß -1 while (basso alto and i < 0): medio ß (basso + alto) / 2 if x = A[medio]: i ß medio else: if x > A[medio]: basso ß medio + 1 else: alto ß medio - 1 medio alto 9 1012 13 15 16 18 20 21 23 24 26 28 x=8

Ricerca di un elemento in un vettore generico ordinato L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x == A[i]; altrimenti ritorna -1 basso 0 1 2 4 5 6 6 basso ß 0 alto ß n -1 i ß -1 while (basso alto and i < 0): medio ß (basso + alto) / 2 if x = A[medio]: i ß medio else: if x > A[medio]: basso ß medio + 1 else: alto ß medio - 1 medio eser4.8.cpp alto 9 1012 13 13 16 18 20 21 23 24 26 26 x=6

Se applicato ad un array ordinato in cui sono possibili ripetizioni l algoritmo termina con successo dando uno dei possibili indici per cui l uguaglianza risulta verificata. E possibile trovare il più piccolo indice per cui l uguaglianza è verificata eliminando il test su i. Il loop si riduce a: basso 0 Alto N-1 while (basso<=alto) Medio (basso+alto) / 2 if x > vet[medio] basso Medio+1 else Alto Medio-1 Osserviamo che allorché x<= vet[medio] noi modifichiamo Alto

Nel caso sia vera la condizione x > vet[medio] allora possiamo affermare che la ricerca va effettuata nel sub-array superiore e che in uscita dal loop si avrà: x > vet[basso-1] (poiché basso-1 = Medio in uscita) inoltre tale condizione resta vera anche quando basso non viene modificato, visto che l elemento basso - 1 è stato escluso dai possibili candidati

Se, invece, è vera la condizione x <= vet[medio] allora la ricerca va effettuata nel sub-array inferiore; inoltre, risulta verificata la condizione x <= vet[alto + 1] (poiché Alto+1=Medio in uscita) Dunque qualunque strada si prende nel loop è sempre vero che in uscita si ha: Vet[basso-1] < x <= vet[alto + 1] Il ciclo termina con la negazione di (basso <= Alto), cioè con basso > Alto

Analizzando gli esempi, possiamo verificare che all uscita si ha basso = Alto + 1 Se in un certo punto del programma risulta che vet[medio] coincide col valore cercato x; nell algoritmo precedente si usciva dal ciclo. In questo caso l algoritmo continua e, poiché siamo nella situazione che segue l else, avremo da cui Alto= Medio 1; Medio = Alto + 1 Quindi il valore cercato è conservato nell indice Alto + 1. Poiché l intervallo con cui proseguire la ricerca è [basso, alto], se gli elementi sono tutti distinti, le ricerche successive non cambieranno mai il valore di Alto, essendo tali elementi più piccoli dell elemento cercato; alla fine il ciclo terminerà con l uguaglianza basso = Alto + 1 e quindi l elemento cercato sarà posizionato nell indice contenuto nella variabile basso.

Nel caso in cui vi siano più elementi uguali, l algoritmo troverà altri indici compresi nell intervallo [basso, alto] che contengono il valore x cercato. Se applichiamo ancora il ragionamento precedente è chiaro che l algoritmo determinerà il primo indice in cui appare x. Cosa accade nel caso in cui l elemento cercato x non esiste nell array? Poiché l algoritmo termina in ogni caso con basso = Alto +1 dobbiamo distinguere il caso in cui l indice basso<=n-1 dal caso particolare in cui basso=n che si verifica se l elemento cercato è più grande di tutti gli elementi dell array. Occorre quindi aggiungere al termine del loop il seguente test: If (basso=n) or not(vett[basso]=x) Indice= -1 else indice = basso

Ricerca di un elemento in un vettore generico ordinato L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x == A[i]; altrimenti ritorna -1 basso 0 1 2 4 5 6 6 9 1012 13 13 16 18 20 21 23 24 26 28 basso ß 0 alto ß n -1 while basso alto: medio ß (basso + alto) / 2 if x > A[medio]: basso ß medio + 1 else: alto ß medio 1 if (basso=n) or (A[basso] ¹ x): indice ß -1 else: indice ß basso medio alto 6

Ricerca di un elemento in un vettore generico ordinato L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x == A[i]; altrimenti ritorna -1 eser4.8b.cpp basso medio alto 0 1 2 4 5 6 6 9 1012 13 13 16 18 20 21 23 24 26 27 basso ß 0 alto ß n -1 while basso alto: medio ß (basso + alto) / 2 if x > A[medio]: basso ß medio + 1 else: alto ß medio 1 if (basso=n) or (A[basso] ¹ x): indice ß -1 else: indice ß basso 27

Ricerca di un elemento in un vettore generico ordinato L operatore = sia la relazione di equivalenza Input: vettore A[0], A[1],..., A[n-1] ; elemento x da cercare in A Output: almeno un i tale che x == A[i]; altrimenti ritorna -1 basso medio alto 0 1 2 4 5 6 6 9 1012 13 13 16 18 20 21 23 24 26 27 basso ß 0 alto ß n -1 while basso alto: medio ß (basso + alto) / 2 if x > A[medio]: basso ß medio + 1 else: alto ß medio 1 if (basso=n) or (A[basso] ¹ x): indice ß -1 else: indice ß basso 30

Ecco un programma che utilizza le due ricerche binarie sotto la forma di functions; esse restituiscono un intero che rappresenta l indice dell elemento cercato. La function RicercaBinB rappresenta la ricerca con la variabile booleana, RicercaBin invece non utilizza tale variabile. #include <iostream> #include <cstdlib> #include "InsertArray.h" using namespace std; int RicercaBinB (int[], int, int, int); int RicercaBin (int[], int, int, int); void ordinab(int[], int n); void scambia (int&, int&); int main () { char ch; int a[100], n, cerca; cout<<" Lunghezza vettore="; cin>>n; LeggeVettore ( a, n, 'a'); ordinab (a,n); StampaVettore (a, n,'a'); do { cout<<"valore da cercare="; cin>>cerca; if ((RicercaBinB(a,0,n,cerca)>=0) (RicercaBin(a,0,n,cerca)>=0)) { cout<<"il valore "<<cerca<<" ha la posizione="<<ricercabinb(a,0,n,cerca)<<endl; cout<<"senza Flag, il valore "<<cerca<<" ha la posizione="<<ricercabin(a,0,n,cerca)<<endl; } else cout<<"il valore "<<cerca<<" non e' nel vettore"<<endl; cout<<" f per terminare "; cin>>ch; } while (ch!='f'); return 0; } void scambia (int &x1, int &x2) { int s; s=x1; x1=x2; x2=s; }

void ordinab ( int vet[], int N) { int j, k; for (k=0; k<n-1; k++) for (j=k+1; j<n; j++) if (vet[k] > vet[j]) scambia (vet[k],vet[j]); } int RicercaBinB ( int vet[], int basso, int alto, int x) { int medio,i=-1; while ((basso<=alto) && i==-1) { medio=(basso+alto)/2; if (vet[medio]==x) i=medio ; else if (vet[medio]<x) basso=medio+1; else alto=medio-1; } return i; } insertarray.h esercizio22.1.cpp int RicercaBin ( int vet[], int basso, int alto, int x) { int medio, Ntot=alto; while (basso<=alto) { medio=(basso+alto)/2; if (vet[medio]<x) basso=medio+1; else alto=medio-1; } if (( basso==ntot) (vet[basso]!=x)) return -1; else return basso; }