PDA

Visualizza la versione completa : [C] - ricorsione che non va del tutto


qotsa
19-12-2008, 13:33
Salve!

le specifiche del mio esercizio sono:

Scrivere una funzione RICORSIVA in linguaggio C in grado di ricevere un vettore di STRUCT di dimensione indefinita. Ogni elemento del vettore contiene una variabile struct con un campo di tipo char, uno di tipo unsigned e uno di tipo long.

Se il campo di tipo char contiene il carattere ’p’ il valore nel campo di tipo unsigned
va considerato positivo; se contiene il carattere ’n’, il valore va considerato negativo.
Il carattere ’t’ rappresenta il valore sentinella, che identifica la fine del vettore.

La funzione deve salvare nel campo di tipo long dell’elemento i il valore della somma parziale
dei campi di tipo unsigned dei primi i + 1 elementi (considerando il segno definito dal
carattere ’p’ o ’n’), fino al raggiungimento dell’elemento contenente il carattere terminatore
’t’.

La funzione main del programma deve quindi popolare i campi di tipo char e unsigned
degli elementi del vettore di struct (che potete dichiarare con dimensione 100), leggendo
la sequenza in input, deve richiamare la funzione ed infine stampare (sempre nel main),
per ogni elemento del vettore, il valore numerico considerando il segno del campo di tipo
unsigned e il valore della somma parziale.
La sequenza di input `e della forma carattere (’n’ o ’p’), seguito da un intero positivo maggiore di 0 (il tutto ripetuto 0 o più volte), ed infine il carattere ’t’.

Esempio: Se l’input `e
p 10 n 10 p 4 p 3 n 5 t
Il programma deve stampare
10 10 -10 0 4 4 3 7 -5 2

e il codice che ho scritto è:

#include<stdio.h>

#define SIZE 100

typedef struct parole{ //struttura
char segno;
unsigned valore;
long sommetta;
}Parole;

void somma_pref(Parole vettorino[], int i); //prototipo della funzione

int main()
{
Parole vettorino[SIZE]={0}; //dichiaro il vettore di struct

int i;

for(i=0; i<SIZE; i++)
{
scanf("%c", &vettorino[i].segno); //prendo il segno del valore
if(vettorino[i].segno=='t') // se è t mi fermo
{
break;
}
scanf("%u", &vettorino[i].valore); //prendo il valore
}

somma_pref(vettorino, 0); //FUNZIONE

for(i=0; vettorino[i].segno=='t'; i++); //stampa
{
printf("%u %ld", vettorino[i].valore, vettorino[i].sommetta);
}

return 0;
}

void somma_pref(Parole vettorino[], int i)
{

if(vettorino[i].segno=='t') //caso base per uscire dalla ricorsione
{
return;
}
if(vettorino[i].segno=='p') //caso p, positività del valore
{
vettorino[i].sommetta+=vettorino[i].valore;
somma_pref(vettorino, i+1); //vado avanti nella ricorsione
}
else if(vettorino[i].segno=='n') //caso n, negatività del valore
{
vettorino[i].sommetta-=vettorino[i].valore;
somma_pref(vettorino, i+1); //vado avanti nella ricorsione
}
}


(scusate i nomi fantasiosi ma lo faccio per divertirmi con gli amici :D )

cmq il problema è che il programma compila ma la ricorsione non va...come risultato ( anche se giusto) mi da solo il primo valore con somma parziale!!! ( a me servirebbero tutti :master: )

non so, potrebbero anche esserci altri errori che io non vedo o non conosco!

grazie :unz:

Xaratroom
21-12-2008, 01:06
puoi "ripostare" il codice includendolo nei tag code ?

qotsa
21-12-2008, 12:25
ma certo!



#include<stdio.h>

#define SIZE 100

typedef struct parole{ //struttura
char segno;
unsigned valore;
long sommetta;
}Parole;

void somma_pref(Parole vettorino[], int i); //prototipo della funzione

int main()
{
Parole vettorino[SIZE]={0}; //dichiaro il vettore di struct

int i;

for(i=0; i<SIZE; i++)
{
scanf("%c", &vettorino[i].segno); //prendo il segno del valore

if(vettorino[i].segno=='t') // se è t mi fermo
{
break;
}
scanf("%u", &vettorino[i].valore); //prendo il valore
}

somma_pref(vettorino, 0); //FUNZIONE

for(i=0; vettorino[i].segno=='t'; i++); //stampa
{
printf("%u %ld", vettorino[i].valore, vettorino[i].sommetta);
}

return 0;
}

void somma_pref(Parole vettorino[], int i)
{

if(vettorino[i].segno=='t') //caso base per uscire dalla ricorsione
{
return;
}
if(vettorino[i].segno=='p') //caso p, positività del valore
{
vettorino[i].sommetta+=vettorino[i].valore;
somma_pref(vettorino, i+1); //vado avanti nella ricorsione
}
else if(vettorino[i].segno=='n') //caso n, negatività del valore
{
vettorino[i].sommetta-=vettorino[i].valore;
somma_pref(vettorino, i+1); //vado avanti nella ricorsione
}
}


:)

Xaratroom
21-12-2008, 13:15
#include <stdio.h>

#define SIZE 100

typedef struct //struttura
{
char segno;
int valore;
long int sommetta;
} Parole;

void somma_pref (Parole vettorino[], int i, long int somma_precedente); //prototipo della funzione

int main()
{
Parole vettorino[SIZE] = {0}; //dichiaro il vettore di struct
int i;

for(i = 0; i < SIZE; i++)
{
scanf (" %c", &vettorino[i].segno); //prendo il segno del valore
if(vettorino[i].segno == 't') // se è t mi fermo
break;
scanf(" %d", &vettorino[i].valore); //prendo il valore
}

somma_pref(vettorino, 0, 0); //FUNZIONE

i = 0;
while (vettorino[i].segno != 't') //stampa
{
printf("%d %ld ", vettorino[i].valore, vettorino[i].sommetta);
i++;
}

return 0;
}

void somma_pref (Parole vettorino[], int i, long int somma_precedente)
{
if(vettorino[i].segno=='t') //caso base per uscire dalla ricorsione
return;

if(vettorino[i].segno == 'n') //caso n, negatività del valore
vettorino[i].valore *= -1; //il valore deve diventare negativo

vettorino[i].sommetta = vettorino[i].valore + somma_precedente;
somma_pref(vettorino, i+1, vettorino[i].sommetta);
}


Controlla se è corretto, rispetto alle consegne ...
E poi dimmi che cosa avevi sbagliato, confrontando i due programmi.

La mia soluzione prevede un campo di tipo int e non usigned int ...
Di conseguenza, se non va bene, devi modificarlo

sotoli
21-12-2008, 15:17
Originariamente inviato da Xaratroom


#include <stdio.h>

#define SIZE 100

typedef struct //struttura
{
char segno;
int valore;
long int sommetta;
} Parole;

void somma_pref (Parole vettorino[], int i, long int somma_precedente); //prototipo della funzione

int main()
{
Parole vettorino[SIZE] = {0}; //dichiaro il vettore di struct
int i;

for(i = 0; i < SIZE; i++)
{
scanf (" %c", &vettorino[i].segno); //prendo il segno del valore
if(vettorino[i].segno == 't') // se è t mi fermo
break;
scanf(" %d", &vettorino[i].valore); //prendo il valore
}

somma_pref(vettorino, 0, 0); //FUNZIONE

i = 0;
while (vettorino[i].segno != 't') //stampa
{
printf("%d %ld ", vettorino[i].valore, vettorino[i].sommetta);
i++;
}

return 0;
}

void somma_pref (Parole vettorino[], int i, long int somma_precedente)
{
if(vettorino[i].segno=='t') //caso base per uscire dalla ricorsione
return;

if(vettorino[i].segno == 'n') //caso n, negatività del valore
vettorino[i].valore *= -1; //il valore deve diventare negativo

vettorino[i].sommetta = vettorino[i].valore + somma_precedente;
somma_pref(vettorino, i+1, vettorino[i].sommetta);
}


Controlla se è corretto, rispetto alle consegne ...
E poi dimmi che cosa avevi sbagliato, confrontando i due programmi.

La mia soluzione prevede un campo di tipo int e non usigned int ...
Di conseguenza, se non va bene, devi modificarlo

Ciao....la tua soluzione funziona, ma secondo me non va bene per il semplice motivo che il testo dell'esercizio dice che il campo valore deve essere unsigned e che quindi deve contenere un valore sempre >= 0, mentre tu usi un int e nella tua funzione lo fai anche diventare negativo moltiplicandolo per -1, dove necessario. Secondo me poi non serve nemmeno il terzo parametro che hai aggiunto alla funzione, perché è comunque sempre raggiungibile cosi:

vettorino[i-1].sommetta
Bisogna solo stare attenti la prima volta che viene richiamata la funzione, cioè quando il parametro i = 0.
Secondo me una funzione così dovrebbe andare:


void somma_pref(Parole vettorino[], int i)
{
if(vettorino[i].segno == 't')
return;
if(i == 0)
vettorino[i].sommetta = (vettorino[i].segno == 'p') ? vettorino[i].valore : -vettorino[i].valore;
else
vettorino[i].sommetta = vettorino[i-1].sommetta + ((vettorino[i].segno == 'p') ? vettorino[i].valore : -vettorino[i].valore);
somma_pref(vettorino, i+1);
}

Xaratroom
21-12-2008, 15:42
Non te la prendere male, ma volevo vedere se ci arrivava lui ...
Del resto è un esercizio quindi non vale la pena di dare la soluzione evitando, al richiedente, ogni possibile ragionamento in proposito.

Cmq hai ragione sulla soluzione (ma è meglio aggiungere un parametro o aggiungere un controllo?)

PS: pensaci un po' su ... cosa potresti fare se tu avessi quel terzo parametro ?

qotsa
27-12-2008, 11:35
grazie ragazzi! finalmente l'esercizio è completato!
:fighet:

:unz:

Loading