[C++] Esercizio appello esame pattern matching [URGENTE]

di il
4 risposte

[C++] Esercizio appello esame pattern matching [URGENTE]

Il testo dell'esercizio è questo:
Il programma richiede di eseguire un pattern matching dove il pattern è costituito dai campi info dei nodi di
un albero binario ordinati secondo il percorso in larghezza, mentre il pattern è semplicemente un array di
dimP interi.
Il problema va risolto in 2 passi:
1) Va definita una funzione iterativa nodoE* faiIter(nodo*r) che restituisce la lista L dei nodi estesi
nodoE che puntano ai nodi di albero(r) percorsi in larghezza.
La struttura nodoE è come segue:
struct nodoE{nodo* info; nodoE* next; nodoE(nodo*a=0, nodoE*b=0){info=a; next=b;}};
nodo è invece il solito nodo degli alberi binary.
2) Va definita una funzione ricorsiva int matchRic(nodoE*L, int*P, int dimP) che riceve la lista L
prodotta nel passo 1, il pattern P e la lunghezza del pattern dimP e restituisce la massima lunghezza
di match di P che si trova nei nodi puntati da L. Infatti il match da considerare può essere anche
incompleto ed è spiegato nell’esempio che segue.
Esempio 1: . Si consideri il seguente albero binario r:
10(5(10(1(_,_),2(_,_)),2(3(_,_),1(_,_))),5(_,1(3(_,_),2(_,_)))) esso contiene 12 nodi.
Allora la lista L che faiIter deve produrre contiene 12 nodi di tipo nodoE. Il primo di essi punta alla
radice r (che ha info=10), il secondo al figlio sinistro (info=5) di r, il terzo al figlio destro (info=5) di
r, il quarto al figlio sinistro del figlio sinistro di r (info=10) e così via. Quindi la sequenza dei campi
info puntati dai nodoE di L sarà: 10,5,5,10,2,1,1,2,3,1,3,e 2. Nel seguito chiamiamo questa sequenza
semplicemente L. Assumiamo ora che P=[2,5,10,2]. Se partiamo dal primo valore di L (10), esso
matcha la terza posizione di P, dopo di che il prossimo valore di L (5) non matcha l’ultimo elemento
di P che è 2. Per cui il match a partire dalla prima posizione di L ha lunghezza 1. Consideriamo ora il
match che parte dalla seconda posizione di L: 5 matcha la seconda posizione di P, poi il successivo 5
non matcha nessun successivo elemento di P. Quindi anche questo match ha lunghezza 1. Partiamo
ora dal terzo elemento di L che è 5, esso matcha il secondo elemento di P, il successivo 10 di L
matcha il terzo elemento di P, e il successivo elemento di L (2) matcha l’ultimo elemento di P.
Quindi abbiamo trovato un match di lunghezza 3. Non è difficile vedere che i successivi tentativi
troveranno match più corti di 3 e quindi la risposta che matchRic dovrebbe dare è 3.
Nota: eventuali funzioni ausiliarie di faiRic devono essere ricorsive e di matchIter devono essere
iterative


La prima parte l'ho fatta utilizzando una struttura FIFO che ha come campi i puntatori nodoE* rispettivamente primo e ultimo. Compilando la prima parte mi risulta corretta invece per quanto riguarda la seconda parte, ci sono degli errori. Ho particolarmente urgenza in quanto domani ho l'appello d'esame quindi se qualcuno mi riesce a spiegare nel dettaglio cosa ho sbagliato mi farebbe un enorme favore. Grazie in anticipo. Vi riporto successivamente il codice che ho scritto:

#include<iostream>
using namespace std;

struct nodo { int info; nodo* left, * right; nodo(int a = 0, nodo* b = 0, nodo* c = 0) { info = a; left = b; right = c; } };
struct nodoE { nodo* info; nodoE* next; nodoE(nodo* a = 0, nodoE* b = 0) { info = a; next = b; } };
struct FIFO {
	nodoE* primo;
	nodoE* ultimo; 
	FIFO(nodo* a = 0) {
		if (a) primo = ultimo = new nodoE(a);
		else
			primo = ultimo = 0;
	}
};

nodo* pop(FIFO& x) {
	nodoE* a = x.primo;
	x.primo = x.primo->next;
	if (!x.primo)
		x.ultimo = 0;
	return a->info;
}

FIFO push(nodo* x, FIFO y) {
	if (y.primo) {
		y.ultimo->next = new nodoE(x);
		y.ultimo = y.ultimo->next;
		return y;
	}
	return FIFO(x);
}

nodoE* faiIter(nodo* r) {
	FIFO coda(r);
	while (coda.primo) {
		nodo* x = pop(coda);
		cout << x->info << " ";
		if (x->left) coda = push(x->left, coda);
		if (x->right) coda = push(x->right, coda);	
	}
	return coda.primo;
}

void stampaLista(nodoE* lista) {
	if (lista) {
		cout << lista->info->info << " ";
		stampaLista(lista->next);
	}
}

bool check(nodoE* lista, int* A, int dimA) {
	if (dimA) {
		if (lista->info->info == *A) return true;
		else {
			return check(lista->next, A + 1, dimA - 1);
		}
	}
	else
		return false;
}

int scorri(nodoE* L, int* A, int dimA,int h) {
	if (!dimA) return h;
	if (L && dimA) {
		if (L->info->info == *A) {
			if (L->next) return scorri(L->next, A + 1, dimA - 1, h++);
			else {
				return ++h;
			}
		}
		else return scorri(L, A + 1, dimA - 1, h);
	}
	if(!L) return h;
}

int matchRic(nodoE* L, int* P, int dimP,int & max) {
	if (!dimP) return 0;
	if (L) {
		if (check(L, P, dimP) == true) { 
			int max2 = scorri(L, P, dimP, 0); 
			if (max2 > max) max = max2;
		}
		else
			return matchRic(L->next, P, dimP,max);
	}
	return max;
}

int main() {
	nodo* albero = new nodo(5, new nodo(10), new nodo(4));
	albero->left->left = new nodo(7);
	albero->left->right = new nodo(2);
	albero->right->right = new nodo(5);
	nodoE* x = faiIter(albero);
	stampaLista(x);
	int max = 0; 
	int A[]{ 2,5,10 }; int dimA = 3;
	cout << matchRic(x, A, dimA, max);

}

4 Risposte

  • Re: [C++] Esercizio appello esame pattern matching [URGENTE]

    Di urgente non c'è nulla, non siamo a disposizione tua
    Se non compila, non è che magari devi mettere la flag -std=c++11? Che errori hai?
  • Re: [C++] Esercizio appello esame pattern matching [URGENTE]

    Weierstrass ha scritto:


    Di urgente non c'è nulla, non siamo a disposizione tua
    Se non compila, non è che magari devi mettere la flag -std=c++11? Che errori hai?
    Mi sono spiegato male, compila ma l'output non è quello desiderato. Ho due warning:
    -'matchRic': not all control paths return a value
    -'scorri': not all control paths return a value
  • Re: [C++] Esercizio appello esame pattern matching [URGENTE]

    Su scorri() è evidente
    all'ultima riga hai
    	if(!L) return h;
    Quindi se L è diverso da zero vai avanti e non hai un return value, ma la funzione deve restituire un int.

    Su matchric() sei sicuro di avere quel warning?
  • Re: [C++] Esercizio appello esame pattern matching [URGENTE]

    Weierstrass ha scritto:


    Su scorri() è evidente
    all'ultima riga hai
    	if(!L) return h;
    Quindi se L è diverso da zero vai avanti e non hai un return value, ma la funzione deve restituire un int.

    Su matchric() sei sicuro di avere quel warning?
    Non ho piu' nessun warning ora ma l'output è 0 e con il test che sto facendo dovrei avere come output 2
Devi accedere o registrarti per scrivere nel forum
4 risposte