Oppure

Loading
19/10/16 15:21
Birkhoff92
Salve come da titolo all'esame di Programmazione I ho svolto l'esercizio i cui mi si chiedevano operazioni sui polinomi, il programma come ammesso anche dal prof era l'unico dei 6 che compilava ed eseguiva ma non mi ha fatto passare l'esame perchè non ho implementato il template ( cosa che a dire il vero era richiesta dal primo punto dei 7 della traccia ). Il problema come gli avevo fatto notare , è che in Eclipse per di più su macchina virtuale mi dava continuamente errori che poi magicamente scomparivano se chiudevo e riaprivo. Ora siccome il problema era il template , io ho svolto senza e cioè così:
MAIN.CPP
#include <stdlib.h>
#include "Polinomio.h"
#include <iostream>
using namespace std;
int main()
{
cout<<"\nCreo e inizializzo la lista\n";
polinomio mylist;
polinodo *p;
init_list(&mylist);
insert(&mylist, 2, 3);
insert(&mylist, 2, 1);
insert(&mylist, 3, 5);
insert(&mylist, 3, 7);
insert(&mylist, 0, 9);

//STAMPA
cout<<"\nStampo la lista: \n"<<endl;
cout<<&mylist;

//CERCA NODO DATO L'ESPONENTE
p=search(&mylist,7);
cout<<"\nCerca \n";
cout<<"\nIl polinodo cercato e': "<<p->coeff<<"x^"<<p->espon<<endl;

//VALUTA IL POLINOMIO IN UN PUNTO
cout<<"\nValuto il polinomio in un punto dato: \n";
double v=eval(&mylist,0.9);
cout<<"\nIl valore calcolato e': "<<v<<endl;

//ADDIZIONO UN NODO AL POLINOMIO
cout<<"\n Effettuo la somma tra il polinomio e un polinodo\n";
add(&mylist,4,7);
cout<<"\n Dopo la somma il polinomio e':\n";
cout<<&mylist<<endl;

//GRADO DEL POLINOMIO
cout<<"\nIl grado del polinomio e': ";
int e=degree(&mylist);
cout<<e<<endl;

//DERIVATA
cout<<"\nLa derivata del polinomio e': \n";
derivata(&mylist);
ordina(&mylist);
cout<<&mylist<<endl;
return 0;
}


POLINOMIO.H
#ifndef POLINOMIO_H
#define POLINOMIO_H
#include <iostream>
using namespace std;
typedef struct Polinodo
{
// informazioni contenute nel nodo
double coeff;
unsigned int espon;
// puntatore al nodo precedente
struct Polinodo *prev;
// puntatore al nodo successivo
struct Polinodo *next;
} polinodo;
typedef struct Polinomio
{
// tiene traccia di quanti nodi sono presenti all'interno della lista
int count;
// puntatore al primo nodo della lista
struct Polinodo *header;
// puntatore all'ultimo nodo della lista
struct Polinodo *tailer;
} polinomio;

void init_list(polinomio *);
void delete_list(polinomio *);
void insert(polinomio *, double,unsigned int );
polinodo *search(polinomio* ,unsigned int);
void delete_node(polinomio *, polinodo );
void delete_value(polinomio *, int );
void print_list(polinomio *);
void add(polinomio *,double,unsigned int);
int degree(polinomio *);
void derivata(polinomio *);
double eval(polinomio *,double);
ostream &operator<<(ostream&,polinomio *);
void ordina(polinomio *);
#endif


POLINOMIO.CPP

#include <stdio.h>
#include <stdlib.h>
#include "Polinomio.h"
#include <iostream>
#include <math.h>

using namespace std;
//INIZIALIZZAZIONE DELLA LISTA
void init_list(polinomio *list)
{
// la lista inizialmente non contiene elementi
list->count = 0;
// sia la testa che la coda puntano inizialmente a NULL
list->header = list->tailer = NULL;
}
//CANCELLAZIONE DELL'INTERA LISTA
void delete_list(polinomio *list)
{
polinodo *n1, *n2;
n1 = list->header;
// scorro i nodi della lista e li cancello
// tramite la funzione free() libero la memoria da essi occupata
while (n1 != NULL)
{
n2 = n1->next;
free(n1);
n1 = n2; }
}
//AGGIUNTA DI UN NUOVO NODO ALLA LISTA
void insert(polinomio *list, double new_coeff,unsigned int new_espon)
{
// creo il nuovo nodo e gli alloco uno spazio di memoria
polinodo *new_node;
new_node = (polinodo*)malloc(sizeof(polinodo));
// inizializzo il nuovo nodo e gli inserisco il nuovo dato
new_node->coeff = new_coeff;
new_node->espon=new_espon;
new_node->next = NULL;
// inserisco il nodo all'interno della lista: due casi possibili
// CASO 1: la lista e' vuota (count e' 0)
// il nuovo nodo fara' sia da header che da tailer
if (list->count == 0)
{
new_node->prev = NULL;
list->header = list->tailer = new_node;
}
// CASO 2: la lista contiene gia' almeno un elemento
// aggancio il nuovo nodo alla fine della lista
// dopo l'inserimento, il nuovo nodo sara' quindi il tailer della lista
else
{
new_node->prev = list->tailer;
list->tailer->next = new_node;
list->tailer = new_node;
}
// aumento il contatore dei nodi della lista
list->count++;
}
//RICERCA DI UN VALORE ALL'INTERNO DELLA LISTA
polinodo* search(polinomio *list,unsigned int e)
{
polinodo *tmp;
tmp = list->header;
// scorro la lista cercando value
// ritorno l'indirizzo del primo nodo che contiene value
// altrimenti continuo a scorrere la lista
while (tmp != NULL)
{

if (tmp->espon == e)
return tmp;
tmp = tmp->next;
}
// se non trovo nessun nodo contenente value, ritorno NULL
return NULL;
}
//CANCELLAZIONE DI UN SINGOLO NODO
void delete_node(polinomio *list, polinodo *n)
{
// sgancio il nodo puntato da n dalla lista
n->prev->next = n->next;
if (n->next != NULL) // previene possibili Segmentation Fault
n->next->prev = n->prev;
// libero la memoria allocata
free(n);
list->count--;
return;
}
//CANCELLAZIONE DEI NODI IN CUI è PRESENTE UN VALORE INDICATO
void delete_value(polinomio *list, int value)
{
polinodo *tmp;
while ((tmp = search(list, value)) != NULL)
delete_node(list, tmp);
return;
}
//STAMPA DI TUTTI I NODI DELLA LISTA
void print_list(polinomio *list)
{
polinodo *tmp;
tmp = list->header;
int i;
for (i = 1; i <= list->count; i++)
{
cout<<"nodo "<<i<<":"<< tmp->coeff<<" "<<tmp->espon<<endl;
tmp = tmp->next;
}
return;
}
void add(polinomio *list,double c,unsigned int e) {
polinodo *temp;
temp=list->header;
for(int i=0;i<list->count;i++)
{
if(temp->espon==e)
temp->coeff+=c;
temp=temp->next;
}
}
int degree(polinomio *list) {
unsigned int e=0;
polinodo* temp;
temp=list->header;
for(int i=0;i<list->count;i++) {
if(temp->espon>e && temp->coeff!=0)
e=temp->espon;
temp=temp->next;
}
return e;
}
void derivata(polinomio * list) {
polinodo *temp;
temp=list->header;
for(int i=0;i<list->count;i++) {
temp->coeff*=temp->espon;
temp->espon-=1;
temp=temp->next;
}
}
double eval(polinomio *list,double x) {
polinodo *temp;
temp=list->header;
double v=0;
for(int i=0;i<list->count;i++) {
v=v+pow((temp->coeff)*x,temp->espon);
temp=temp->next;
}
return v;
}
ostream& operator<<(ostream& os,polinomio *list) {
polinodo *temp;
temp=list->header;
cout<<"\nIl polinomio e':\n";
for(int i=0;i<list->count;i++) {
cout<<"+"<<temp->coeff<<"x^"<<temp->espon;
temp=temp->next;
}
return os;
}



void ordina(polinomio *list) {
polinodo *temp;
temp=list->header;
double c;
unsigned int e;

for(int i=0;i<list->count;i++) {

for(int j=0;j<(list->count)-1;j++) {
if(temp->espon<temp->next->espon) {
c=temp->coeff;
e=temp->espon;
temp->espon=temp->next->espon;
temp->coeff=temp->next->coeff;
temp->next->coeff=c;
temp->next->espon=e;
}

}
temp=temp->next;

}
}
ora mi chiedo col template come lo potrei modificare ? Grazie e scusate per il disturbo.
aaa
19/10/16 16:04
lumo
Difficile da dire senza traccia, probabilmente invece dei coefficienti double avresti dei coefficienti generici di tipo T.
A quel punto in ogni posto dove ora hai un polinomio* dovresti avere un polinomio<T>* e così via.

Hai il codice modificato, anche se non funziona? La macchina virtuale ed Eclipse non c'entrano nulla, probabilmente hai sbagliato qualcosa nella sintassi che è abbastanza scivolosa.
aaa
19/10/16 16:19
Birkhoff92
Grazie per la risposta innanzitutto. Allora la traccia era :
Scrivere un programma che soddisfi i seguenti requisiti:
Sviluppare un template di classe Polinomio. La rappresentazione interna di un Polinomio è una lista a puntatori. Ciascun termine è costituito da un coefficiente ed un esponente. Il termine 2x^4 ha come coefficiente 2 ed esponente 4. I coefficienti sono memorizzati dall'esponente più piccolo a quello più grande. Inoltre ogni polinomio possiede un puntatore che punta al nodo al quale si è avuto accesso di recente.
Sviluppare una classe completa di costruttore e distruttore. Inoltre si costruiscano le funzioni set e get. La classe deve inoltre possedere i seguenti altri operatori sovrapposti:
a) operator(+) per sommare due polinomi;
b)operator(-) per sottrarre due polinomi;
c) operator(=) per assegnare un polinomio ad un altro;
d)operator(*) per moltiplicare due polinomi. Operator(+=) per la somma e l'assegnazione contratta, operator(-=) per la sottrazione ed assegnazione contratta, operator(*=) per la moltiplicazione e assegnazione contratta(opzionale)
e)si costruisca una classe eccezione polinomio che gestisca tutte le eccezioni di errore che si possono presentare in un polinomio. Si includa tale classe tramite la relazione di composizione.
Tutto questo in 60 minuti.
Ultima modifica effettuata da Birkhoff92 19/10/16 16:22
aaa
19/10/16 16:42
lumo
Beh non so adesso se in italiano "template di classe" vuol dire template class, io l'avrei letto come "bozza di classe".
Supponendo comunque che si dovessero usare i template (che però non hanno molto senso in questo caso), non hai comunque rispettato la traccia. Non hai implementato gli operatori custom (+, -, * e =) e la classe eccezione.
Tra l'altro invece di usare una classe hai usato una struttura senza metodi.

Praticamente il tuo non è un programma in C++, ma un programma in C.

Riguardo ai template, penso che l'unica cosa generalizzabile siano i coefficienti del polinomio, anche se non ha molto senso: mettendoli come double va più o meno bene anche per polinomi a coefficienti interi.
aaa
20/10/16 20:38
Birkhoff92
capito grazie mille ;)
aaa