|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
[C] Qualcuno sa risolvere quest'esercizio in C?
Ecco il testo (grazie x chi mi può aiutare):
Scrivere una funzione ricorsiva occPorzFinale che, data una lista semplice di stringhe, una stringa s e un numero positivo n (> 0) calcola il numero di occorrenze della stringa nella porzione finale della lista specificata dal numero n. Il prototipo della funzione è: int occPorzFinale(Lista str l, char *s, int n, int *distFine) dove in distFine è restituita la lunghezza della lista. Deve essere dichiarato il tipo utilizzato per definire le liste. Non si possono usare funzioni ausiliarie n´e variabili globali nè variabili static. Esempio: l = [Vedi, in, questi, silenzi, in, cui, le,cose] occPorzFinale(l, in,4,&distFine) = 1 occPorzFinale(l, in,3,&distFine) = 0 Ecco il codice, senza la funzione... Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct elem_s {
char *val;
struct elem_s * next;
} elem_str;
typedef elem_str * Lista_str;
int occPorzFinale(Lista_str l, char *s, int n, int *distFine) {}
int main() {
Lista_str a=(elem_str*)malloc(sizeof(elem_str));
Lista_str b=(elem_str*)malloc(sizeof(elem_str));
Lista_str c=(elem_str*)malloc(sizeof(elem_str));
Lista_str d=(elem_str*)malloc(sizeof(elem_str));
int distFine=0;
a->val="silenzi";
a->next=b;
b->val="in";
b->next=c;
c->val="cui";
c->next=d;
d->val="cose";
d->next=NULL;
//printf("%d",distFine);
printf("%d", occPorzFinale(a,"in",2,&distFine));
}
|
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2787
|
Quote:
|
|
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
l = Vedi-> in-> questi-> silenzi-> in-> cui-> le->cose->NULL e chiamo la funzione occPorzFinale(l, in,4,&distFine) n quindi è =4, devo considerare solo la porzione di lista degli ultimi 4 elementi ovvero in->cui->le->cose->NULL in cui la parola in compare. In questo caso la funzione dà esito 1 perchè "in" viene trovato. Se chiamo invece occPorzFinale(l, in,3,&distFine), in non viene trovato perchè non esiste nella porzione finale di lista cui->le->cose->NULL In distFine và memorizzato invece la lunghezza della lista cioè il valore 8. |
|
|
|
|
|
|
#4 | |||
|
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16213
|
Quote:
Perche' non provi a farlo tu, ci dici dove incontri difficolta', e vediamo di darti una mano? In questo modo, il lavoro rimarrebbe comunque in gran parte tu, e tu impareresti molto di piu' che facendotelo semplicemente risolvere da qualcun altro Intanto, ti faccio qualche osservazione sul codice: Quote:
Quote:
Il resto del codice, grosso modo, andava bene. Per occPorzFinale, secondo me te la cavi con le funzioni di libreria dichiarate in string.h: devi solo fare un po' di attenzione.
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu |
|||
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Feb 2004
Messaggi: 1454
|
dunque, se ho capito il problema, la funzione dovrebbe semplicemente vedere con un blocco if se l'ultimo elemento corrisponde alla stringa cercata, per poi richiamare se stessa, operando sulla lista di distFine - 1 elementi (ovvero controllando l'elemento precedente), e fermandosi quando si è autorichiamata n volte.
non so il c, ti faccio un algoritmo generico "visualbasiccheggiante": occPorzFinale(Lista_str l, char *s, int n, int *distFine) if n = 0 then return 0 else . if l(*distFine) = *s then ... return occPorzFinale(l, s, n - 1, int distFine - 1) + 1 . else ... return occPorzFinale(l, s, n - 1, distFine - 1) + 0 . endif endif |
|
|
|
|
|
#6 | ||||
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
Questà è la mia bozza di funzione...ovviamente non funziona...sapete darmi una mano? Codice:
int occPorzFinale(Lista_str l, char *s, int n, int *distFine) {
if (!l) return 0;
if ((*distFine)<n) {
*distFine=*distFine+1;
if (strcmp(l->val, s)==0)
return 1;
else
return 0;
}
return 0+occPorzFinale(l->next,s,n,distFine);
}
Quote:
Quote:
Quote:
|
||||
|
|
|
|
|
#7 | ||
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
Quote:
Ultima modifica di alebertaz : 04-07-2006 alle 10:16. |
||
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Feb 2004
Messaggi: 1454
|
Quote:
ah, ovviamente per l(distFine) io intendo il distFine-esimo elemento della lista, se l'index parte da 0 dovremo usare l(distFine - 1) Ultima modifica di Furla : 04-07-2006 alle 11:21. |
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
|
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
vabbé, in ogni caso se dice lista devi fare una lista. Tu invece fai n elementi a,b,c ... e poi passi solo "a" alla funzione io farei: Codice:
elem_str list[] =
{
{ "pippo", NULL },
{ "pluto", NULL },
{ "pape" , NULL },
{ "papi" , NULL },
{ "papin", NULL },
{ "papi" , NULL },
{ "" , NULL }
};
poi setto i puntatori next della lista: Codice:
int i = 0;
while(1)
if (strlen( list[i].val) )
list[i].next = &list[++i];
else break;
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
la lista deve essere implementata usando questa struttura dati senza indicizzazione: Codice:
typedef struct elem_s {
char *val;
struct elem_s * next;
} elem_str;
typedef elem_str * Lista_str;
|
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
comunque una lista é intesa come 1 oggetto contenente una serie di valori. Tu invece stai facendo n liste contenenti 1 valore. se fai tante liste "a","b","c","d","e",... e poi chiami la funzione passando solo "a" come fa la funzione a sapere cosa c'é dentro "b","c", ... ?
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
a e b sono due oggetti lista elem_str. La lista composta da a e b può essere scritta così: Lista_str lista=a; Per scorrere tutta la lista: while (lista) { //fai qualcosa lista=lista->next; } ... |
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Nov 2004
Messaggi: 357
|
Quote:
quando vuoi aggiungere un elemento ad una linked list, devi allocare memoria per un ELEMENTO, non per una lista di elementi come fai tu. Dopo aver allocato l'elemento ed averlo definito, ne passi l'indirizzo al puntatore next. Per inserire l'elemento successivo farai un lista=lista->next; avendo cura di mantenere una variabile con il puntatore alla radice della lista In definitiva la struttura tipo sarà UN puntatore all'elemento corrente della lista, UN puntatore alla radice della lista, UN puntatore all'elem_str che verrà allocato ad ogni inserimento Ultima modifica di Andlea : 04-07-2006 alle 13:01. |
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
eppure ho fatto anche il professore mi spiace alebertaz, se si potesse con carta e penna (o lavagna e gesso) sarebbe tutto cosí semplice
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#16 |
|
Member
Iscritto dal: May 2006
Messaggi: 69
|
Io l'ho risolto
- Prima di tutto ho trovato il modo di contare il numero di elementi nella lista; - Poi ho cercato di contare le occorrenze della stringa nella lista; - Infine ho preso solo le occorrenze nelle n posizioni finali. Mettendo tutto insieme ecco cosa mi è uscito: Codice:
int occPorzFinale(Lista_str l, char *s, int n, int *distFine)
{
int c = 0; // Conta le occorrenze della stringa
int intPosCorr; // Salva la posizione corrente nella lista
// Controlla che la lista non sia finita
if(l != NULL)
{
// Aggiorna il numero di elementi della lista
(*distFine)++;
// Salva il numero di elementi
intPosCorr = (*distFine);
// Chiama nuovamente la funzione
c = occPorzFinale(l->next, s, n, distFine);
// distFine ora contiene il numero totale di elementi
// c contiene le occorrenze trovate finora
// Controlla che la stringa nella posizione corrente della lista sia uguale
// a quella cercata e controlla anche che essa si trovi negli ultimi n elementi
// della lista
if( (strcmp(l->val, s) == 0) && ((*distFine)-intPosCorr+1 <= n) )
// Un'altra occorrenze trovata!!!
c++;
}
// Restituisce le occorrenze trovate finora
return c;
}
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
AAAAAAAAAAAAAAAAAAAAAAH!!!!
![]() ho fatto un errore! Quote:
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
ma per farla funzionare correttamente la riga in neretto é: Codice:
if( (strcmp(l->val, s) == 0) && ((*distFine)-intPosCorr >= n) )
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Aug 2004
Città: Padova
Messaggi: 1870
|
Quote:
Ottimo esordio nel forum uReverendo Domani con calma controllo Grazie a tutti per l'aiuto |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 14:44.




















