Консультация № 184483
17.11.2011, 02:17
250.47 руб.
0 5 1
Здравствуйте!
У меня возникли сложности с таким вопросом:

Требуется написать программу из области объектно-ориентированного программирования на С++. В Microcoft Visual Studio 2005. Код прокомментировать. Буду благодарна за помощь.

первая часть задания сделана но некоторые функции не работали или не совсем так как требовали.
просьба исправить их и переделать выделение памяти со статической на динамическую.
Задача:
Разработать класс «полином » в соответствии со следующим заданием:
Состояние класса-
Полином задается значениями коэффициентов типа double и определяется степенью полинома и значениями коэффициентов, например полином 4*х**2+7.5*х -3.9 задается степенью 2 и значениями коэффициентов{4.0,7.5.-3.9}. пункт 3. было(Память под полином выделяется статически, во время компиляции, и задается массивом фиксированного предельного значения (например, максимальная степень полинома равна 20).)
Протокол класса –
Определяет возможности создания и инициализации экземпляров класса и правила использования их (методы класса).
Предусмотреть следующие возможности:
-пустой конструктор для инициализации экземпляров и массивов экземпляров класса по умолчанию;
-создание экземпляров класса с инициализацией полинома нулевой степени («константа»)
- создание экземпляров класса с инициализацией степенью полинома и значениями его коэффициентов;
-ввод экземпляров класса из входного потока и вывод их значений в выходной поток (с помощью перегруженных оператор >> и <<);
-выполнение операции сложения двух полиномов (с помощью перегруженного оператора сложения + ). должен получаться новый экземпляр класса не изменяя исходного. с выводом на экран. плюс пользователь должен ввести второй полином.
-вычисление значения полинома в некоторой заданной точке;
-получение полинома для производной от данного полинома (с помощью перегруженного оператора () ); производная от исходного полинома. тоже должен получиться отдельный экземпляр класса. с выводом на экран
-деление многочлена на двучлен вида(x-b)(то есть, для деления задается только коэффициент b);результатом деления является новый полином и остаток (значение типа double); также новый экземпляр класса. и с вывод на экран.
-определение нуля полинома на заданном промежутке (то есть, значение аргумента х ,при котором полином обращается в нуль; для определения существования и единственности корня на отрезке проверить условие сохранения знака первой и второй производных) методом половинного деления. функция bool. если корни есть возвращает корень. или что корней нет.
2.проектирование класса рекомендуется начать с представления состояния класса, учитывающего заданные операции, а затем реализации конструкторов и перегруженного оператора вывода. Для отладки и исчерпывающего тестирования других методов разработанного класса реализовать диалоговую программу, которая позволяет вводить параметры, отлаживаемых методов. Для обработки ошибочных ситуаций использовать механизм исключительных ситуаций.
3.разработку класса при условии, что память под полином необходимой длины выделяется динамически, во время выполнения программ(с помощью оператора new;память задается указателем на double в состоянии класса)
Дополнить интерфейс следующими возможностями:
-создание экземпляра класса с его инициализаций другим экземпляром класса(копирующий конструктор;) вроде сделано, проверить
-переопределение экземпляра класса(с помощью перегруженного оператора присваевания) вроде сделано, проверить
4.написать прикладную программу, использующую разработанный класс.

в функии main сделать циклично меню с выполнением всех нужный пунктов.

Приложение:
то что уже написанно но работает неправильно и не все пункты. либо не совсем так как требуют.

#include <iostream>
using namespace std;

class Poly{
private:
static const int MAX=20;
double mas[MAX+1]; // массив коэффициентов
int k; // степень полинома
int used; // количество использованных элементов массива

public:
Poly(): k(0) { mas[0] = 0.0; }; // пустой конструктор для инициализации экземпляров и массивов экземпляров класса по умолчанию
Poly(float c): k(0) { mas[0] = c; }
Poly(int s, float koef[]);
Poly( const Poly & p ); // копирующий конструктор
~Poly(){};

void Init(const int k, char * mas );
Poly&Poly::Delen(const int n); //деление многочлена на двучлен
//Poly Delen(float b, float& r) const; //нужно чтоб получался отдельный экземпляр класса а не этот изменять.
friend istream & operator >> ( istream & in, Poly & p ); // ввод экземпляров класса из входного потока
friend ostream & operator << ( ostream & out, const Poly & p ); // вывод в выходной поток
Poly & operator + ( const Poly & p ); // сложение двух полиномов
//Poly operator + ( const Poly & p ); // должен получиться отдельный экземпляр класса

float Calc( const float x ) const; // вычисление полинома в заданной точке
Poly & operator () (); // получение полинома для производной от данного полинома
//Poly operator () (); // должен получиться отдельный экземпляр класса
Poly & operator = ( const Poly & p );
//bool Null(float a, float b, float& z) const; // определение нуля полинома на заданном промежутке a,b. Z -ответ
};

// копирующий конструктор
Poly::Poly( const Poly & p ){
this->Init( p.k, (char*) &p.mas );
}

// функция инициализации
void Poly::Init(const int k, char * mas){
if ( this->k=k ){
memcpy( &this->mas, mas, (this->k+1)*sizeof(double) );
this->used = this->k+1;
}
}

// ввод экземпляров класса из входного потока
istream & operator >> ( istream & in, Poly & p ){
double mas[p.MAX];
int k = -1;
cout << "please, enter the poly power: ";
while ( k < 0 || k > p.MAX - 1 )
in >> k;
cout << "please, enter the poly koefficients: " << endl;
for ( int i = 0; i < k + 1; i++ )
{
cout << "k(x) to power[" << k + 1 - i << "]:";
in >> mas[i];
}
p.Init( k, (char*)&mas );
return in;
}

// вывод полинома в выходной поток
ostream & operator << ( ostream & out, const Poly & p ){
out << "P(x)=";
if ( !p.k )
{
out << "0";
return out;
}
for ( int i = p.k; i >= 0; i-- ){
if ( i < p.k ){
if ( p.mas[p.k-i] >= 0 )
out << " + ";
else
out << " ";
}
out << p.mas[p.k-i];
if ( i > 0 )
out << "*x";
if ( i > 1 )
out << "^" << i;
}
out << endl;
return out;
}

// сложение двух полиномов
Poly & Poly::operator + ( const Poly & add ){
for ( int i = 0; i < this->used; i++ ){
if ( i <= add.used )
this->mas[i]+=add.mas[i];
}
return *this;
}

// вычисление полинома в заданной точке
float Poly::Calc( const float x ) const {
float temp, f = 0.0;

for ( int i = this->k; i >=0; i-- ){
if ( i > 0 )
temp = x;
else
temp = 0;
for ( int j = 0; j < i - 1; j++ )
temp *= x;
if ( temp )
f += this->mas[this->k-i] * temp;
else
f += this->mas[this->k-i];
}
return f;
}

// получение полинома для производной от данного полинома
Poly & Poly::operator ()(){

if ( this->k ){
this->k--;
this->used--;
}
if ( this->k )
for ( int i = this->k; i >=0; i-- ){
float temp = this->mas[this->k-i];
for ( int j = 0; j < i; j++ )
this->mas[this->k-i] += temp;
}
return *this;
}

// деление
Poly&Poly::Delen(const int n){

if ( this->k ){
this->k--;
this->used--;
}
if ( this->k )
for ( int i = this->k; i >=0; i-- ){
float temp = this->mas[this->k-i];
this->mas[this->k-i] = temp;
}
//this->mas[k+1]=this->Calc(n);
this->used++;
cout <<"Delenie mnogochlena na dvychlen: "<<endl;
cout << *this;
cout <<"Ostatok"<< this->Calc(n)<< "/x-"<<n;

return *this;
}




// переопределение экземпляра класса
Poly & Poly::operator = ( const Poly & p ){
this->Init( p.k, (char*) &p.mas);
return * this;
}


int main(){
int n;

Poly p;

// ввод полинома с клавиатуры (пример: 4x^2+7.5^x-3.9)
cin >> p;
// вывод полинома на экран
cout <<"Vivod polinoma na ekran:"<<endl;
cout << p;
// использование копирующего конструктора
cout <<"Ispolzovanie kopiryushego konstryktora:"<<endl;
cout << "p: ";
Poly a(p);
// вывод скопированного полинома на экран
cout <<"Vivod skopirovannogo na ekran:"<<endl;
cout << "a: ";
cout << a;
// вычисление полинома в точке с координатой х = 3
cout <<"Vvedite tochky dlya vichisleniya polinoma: ";
cin >>n;
cout <<"Vivchislenie polinoma v tochke:"<<endl;
cout << "x="<<n<<endl;
cout << a.Calc(3) << endl;
// получение производной от полинома
cout <<"Proizvodnaya ot polinoma:"<<endl;
p();
cout << "p: " << p;
// сложение двух полиномов
cout <<"Slogenie dvyx polinomov:"<<endl;
Poly r(a),s(a);
p = r + s;
cout << "p: ";
cout << p;
cout <<"Vvedite b dly deleniya na dvychlen x-b:"<<endl;
cin >> n;
cout <<"Delenie polinoma na dvychlen:"<<endl;
a.Delen(n);
while(1);

return 0;
}

Обсуждение

Неизвестный
22.11.2011, 13:20
общий
Уважаемые эксперты! помогите пожалуйста!
Неизвестный
22.11.2011, 17:36
общий
Постараюсь сделать сегодня или завтра.
Неизвестный
24.11.2011, 17:57
общий
Спасибо большое буду ждать
Неизвестный
25.11.2011, 15:09
общий
это ответ
Здравствуйте, Tigresska!
Вот вариант решения Вашей задачи. Для деления использована схема сокращённого деления Горнера. Для поиска корней - метод простых итераций.
Чтобы суммирование возвращало новый экземпляр, сделала его дружественной функцией (можно было, конечно, и в методе так сделать, но так красивее мне показалось).
Код в приложении, из комментариев должно быть всё ясно. Будут вопросы, обращайтесь.

Удачи!

Приложение:

#include <conio.h>
#include <iostream>
using namespace std;

class Poly{
private:
double *mas; // массив коэффициентов
int k; // степень полинома

public:
Poly(): k(-1), mas (NULL) {}; // пустой конструктор для инициализации экземпляров и массивов экземпляров класса по умолчанию
Poly(double c);
Poly(int s, double* koef);
Poly( const Poly & p ); // копирующий конструктор
~Poly();

void Delen(const double n, Poly &res, double &R); //деление многочлена на двучлен
void Init (const int k_, double * mas_ ); //инициализация

double Calc( const double x ) const; // вычисление полинома в заданной точке
bool Root (double &root, double x1, double x2); //вычисление корня
Poly operator () (); // получение полинома для производной от данного полинома
Poly & operator = ( const Poly & p ); //оператор присваивания

friend istream & operator >> ( istream & in, Poly & p ); // ввод экземпляров класса из входного потока
friend ostream & operator << ( ostream & out, const Poly & p ); // вывод в выходной поток
friend Poly operator + (const Poly &p1, const Poly &p2); //оператор суммы
private:
void Clear (); //очистка
};

// копирующий конструктор
Poly::Poly( const Poly & p )
{
mas = NULL; //помечаем как непроинициализированный
Init( p.k, p.mas ); //инициализируем данными входящего класса
}

Poly::Poly(double c): k(0) //инициализация одним числом
{
mas = new double [1];
mas[0] = c;
}

Poly::Poly(int s, double* koef)
{
mas = NULL;
Init (s, koef);
}

Poly::~Poly()
{
if (mas!=NULL) delete [] mas; //очищаем память
}

// функция инициализации
void Poly::Init(const int k_, double * mas_)
{
k = k_;
if (mas!=NULL) delete [] mas; //удаляем, если что-то уже есть
mas = new double [k+1]; //выделяем память
memcpy( mas, mas_, (k+1)*sizeof(double) ); //копируем данные

}

void Poly::Clear ()
{
k = -1;
if (mas!=NULL) delete [] mas;
}

bool Poly::Root (double &root, double x1, double x2) //возвращает ниличие корней, сам корень в root
{
Poly f1 = (*this)(); //ищем первую производную
Poly f2 = f1(); //ищем вторую производную как производную от первой
if (f1.Calc (x1)*f2.Calc(x1)<0) return false; //проверяем их на разнознаковость
double t = (x1+x2)/2.0; //берём середину
double left = x1, rgt = x2;
double z = Calc(t); //считаем значение
while (abs(z)>0.0001) { //пока не достигнем заданной точности
if (z*Calc(left)<0) //выставляем новые границы отрезка в зависимости от разнознаковости
rgt = t;
else left = t;
t = (left+rgt)/2.0; //новая середина
z = Calc(t); //новое значение
}
root = t; //возвращаем корень
return true;
}

// вычисление полинома в заданной точке
double Poly::Calc( const double x ) const
{
double temp = 1, f = 0.0;

for ( int i = 0; i < k+1; i++ ) {
f+= (temp*mas[i]); //домножаем на коэффициент и суммируем
temp*=x; //накапливаем степень х
}
return f;
}

// получение полинома для производной от данного полинома
Poly Poly::operator () ()
{
Poly res;
res.k = k-1; //понижаем степень
res.mas = new double [k]; //выделяем память
for (int i = 1; i<k+1; i++)
res.mas[i-1] = mas[i]*i; //получаем новые коэффициенты путём умножения на степень
return res;
}

// деление
void Poly::Delen(const double n, Poly &res, double &R)
{
res.Clear (); //очищаем входящий полином
res.k = k-1; //понижаем степень
res.mas = new double [k]; //выделяем память
double t = 0;
for (int i = k-1; i>=0; i--) {
res.mas[i] = mas[i+1] + n*t; //вычисляем по реккурентной формуле
t = res.mas[i];
}
R = mas[0]+n*res.mas[0]; //вычисляем остаток
}

// переопределение экземпляра класса
Poly & Poly::operator = ( const Poly & p )
{
Init( p.k, p.mas); //инициаизируем входящим
return * this;
}

Poly operator + (const Poly &p1, const Poly &p2)
{
const Poly &max = p1.k>p2.k ? p1 : p2; //выбираем полином большей степени
const Poly &min = p1.k>p2.k ? p2 : p1; //и меньшей
Poly res;
res.k = max.k; //новый будет соответсвовать большей
res.mas = new double [max.k+1];
for (int i = 0; i<max.k+1; i++) {
res.mas[i] = max.mas[i]; //пишем коэффициент более длинного
if (i<min.k+1) res.mas[i]+=min.mas[i]; //если более короткий не закончился, суммируем
}
return res;
}


istream & operator >> ( istream & in, Poly & p )
{
int k = -1;
cout << "please, enter the poly power: ";
while ( k < 0 )
in >> k;
cout << "please, enter the poly koefficients: " << endl;
double *mas = new double [k+1];
for ( int i = k; i >= 0; i-- )
{
cout << "x^" << i << ": ";
in >> mas[i];
}
p.Init (k, mas);
return in;
}

// вывод полинома в выходной поток
ostream & operator << ( ostream & out, const Poly & p )
{
if ( p.k<0 )
{
out << "Not exists";
return out;
}
out << "P(x) = " << p.mas[p.k] << "*x^" << p.k << " + ";
for ( int i = p.k-1; i >= 0; i-- ){
out << p.mas[i];
if (i!=0) out << "*x^" << i << " + ";
}
out << endl;
return out;
}

char Menu ()
{
system("cls");
cout << "1. Нахождение суммы полиномов.\n";
cout << "2. Нахождение значение полинома в точке.\n";
cout << "3. Нахождение производной полинома.\n";
cout << "4. Нахождение корня полинома на отрезке.\n";
cout << "5. Деление полинома.\n";
cout << "6. Выход.\n";
cout << "Выберите пункт: ";
char c;
cin >> c;
return c;
}

void p1 ()
{
system("cls");
Poly p1, p2;
cin >> p1;
cin >> p2;
cout << p1+p2;
cout << "\nНажмите любую клавишу";
getch();
}

void p2 ()
{
system("cls");
Poly p1;
cin >> p1;
double x;
cout << "x = ";
cin >> x;
cout << "\nP = " << p1.Calc (x);;
cout << "\nНажмите любую клавишу";
getch();
}

void p3 ()
{
system("cls");
Poly p1;
cin >> p1;
cout << "\nP' = " << p1();
cout << "\nНажмите любую клавишу";
getch();
}

void p4 ()
{
system("cls");
Poly p1;
cin >> p1;
double a, b, x;
cout << "\nВведите границы отрезка: ";
cin >> a >> b;
if (!p1.Root (x, a, b)) cout << "\nКорней нет";
else cout << "x = " << x;
cout << "\nНажмите любую клавишу";
getch();
}

void p5 ()
{
system("cls");
Poly p1, p2;
cin >> p1;
double a, r;
cout << "\na = ";
cin >> a;
p1.Delen (a, p2, r);
cout << "\nРезультат:";
cout << p2;
cout << "Остаток: " << r;
cout << "\nНажмите любую клавишу";
getch();
}

int main()
{
setlocale (LC_ALL, "russian");
bool exit = true;
while (exit) {
char c = Menu();
switch (c) {
case '1':
p1();
break;
case '2':
p2();
break;
case '3':
p3();
break;
case '4':
p4();
break;
case '5':
p5();
break;
case '6':
exit = false;
break;
default:
cout << "Ошибка ввода!";
getch();
}
}
return 0;
}
5
Сделали все просто отлично))) спасибки))
Неизвестный
26.11.2011, 01:24
общий
Спасибо Огромное вам!!! сейчас буду разбираться как это работает.
Форма ответа