Newsgroup: it.comp.lang.c
Titolo: algoritmo per il polinomio

Sto scrivendo un programma per la risoluzione di un polinomio reale p(x) di
grado n del tipo:
p(x) = a0 + a1*x + a2*x^2 + ... + an*x^n
Scritto cosi' fa un po' schifo, ma spero che si capisca! Sto usando la
Regola di Horner che ad esempio, nel caso di un polinomio di quinto grado si
scrive cosi':
p(x) = a0 + x(a1 + x(a2 + x(a3 + x(a4 + x(a5)))))
Ho gia' fatto una funzione calcola() iterativa ma vorrei fare una versione
ricorsiva tipo quella che ho scritto qui sotto che ovviamente non funziona
perche' e' una bozza. I problemi sono tre principalmente: l'assegnazione s=p
viene effettuata ad ogni esecuzione della funzione mentre dovrebbe essere
eseguita solo la prima volta; ne segue il secondo problema, ovvero
l'incremento s++ (in modo che nel prossimo ciclo lavori sulla variabile
successiva dell'array) che a questo punto non ha senso se dopo viene
effettuata l'assegnazione s=p; il terzo problema e' che dovrei fare un
controllo in modo che quando l'array e' finito, la funzione ritorni... ho
scritto if (!s) che equivale a if (s==NULL) ma se l'utente come coefficiente
inserisce uno 0, questo viene interpretato come NULL e la funzione ritorna.
Un' altra richiesta: nella funzione InputDouble viene passata una stringa di
testo che indica all'utente cosa deve inserire e un numero che indica
l'indice del coefficiente ma nel caso del termine noto e del valore della x
non mi serve nessun indice. Per ovviare a questo problema nel momento della
chiamata a InputDouble passo lo 0 come parametro, pero' non credo sia la
soluzione migliore... cioe' e' un po' rozza e poco elegante. Come potrei
modificarla?
#include <stdio.h>
double calcola(double p[], double x);
double InputDouble(char *s,int esp);
int InputInt(char *s);
void main()
{
 double p[10], x, ris;
 int n,i;
 printf("\nCalcolo di un polinomio di grado n in x");
 n=InputInt("\nInserisci il grado di p: ");
 for(i=0; i<n; i++)
  p[i]=InputDouble("Inserisci il coefficiente di x^%d: ",n-i);
 p[++i]=InputDouble("Inserisci il termine noto: ",0);
 x=InputDouble("Inserisci il valore della variabile x: ",0);
 ris=calcola(p,x);
 printf("\nIl polinomio vale %lf",ris);
 getchar();
}
double calcola(double p[], double x)
{
 double ris, *s;
 s=p;    /* uso un puntatore s poiche' non posso modificare il valore del
puntatore p */
 if (!s) return ris;    /* dovrebbe uscire dopo che ha usato tutti i
coefficienti, termine noto compreso */
 ris=*(s++) + x*(calcola(p,x));    /* questa e' l'applicazione della Regola
di Horner */
 return ris;
}
int InputInt(char *s)
{
 int n,valido,risulta;
 do {
  printf(s);
  risulta=scanf("%d",&n);
  if (risulta!=EOF) while (getchar()!='\n')
        ;
  valido=(risulta && n>=1 && n<=10);
  if(!valido)
   printf("\nDevi inserire un intero compreso tra 1 e 10");
 } while (!valido);
 return n;
}
double InputDouble(char *s,int esp)
{
 double coeff;
 int risulta,valido;
 do {
  printf(s,esp);
  risulta=scanf("%lf",&coeff);
  if (risulta!=EOF) while (getchar()!='\n')
        ;
  valido=(risulta==1);
  if(!valido)
   printf("Devi inserire un numero reale\n");
 } while (!valido);
 return coeff;
}

InputDouble("Inserisci il coefficiente di x^%d: ",n-i);
pasasare:
InputDouble(stringa);
dove stringa sia una stringa precedentemente formattata?!?
Tommy

 dove stringa sia una stringa precedentemente formattata?!?
ho inserito all'interno del ciclo for questa istruzione: s="Inserisci il
coefficiente di x^%d",n-i; dove s e' un puntatore a char, ma mi stampa
sempre lo stesso esponente. Cioe' se io ho inserito 3 come grado massimo, mi
stampa sempre x^3.

 stampa sempre x^3.
se usi sprintf() risolvi il problema. con sprintf formatti una stringa nello
stesso modo in cui printf lo fa, possi passi la stringa alla funzione, seza
esp, e poi stampi all'interno della funzione il contenuto della stringa.
Tommy

 degli elementi dell'array in uso.
Ok, grazie! Finalmente adesso mi funziona:
double calcola(double p[], double x, int n)
{
 if (!n) return *p;
 p++;
 return (*(p-1) + x * calcola(p,x,n-1));
}
che poi si potrebbe scrivere anche cosi:
double calcola(double p[], double x, int n)
{
 if (!n) return *p;
 return (*--p + x * calcola(p++,x,n-1));
}
ma forse e' meglio utilizzare la prima forma... questa e' un po' confusa.