2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3  След.
 
 Программа для работы с многочленами на С++
Сообщение30.03.2009, 18:51 


09/09/08
30
Россия
необходимо с использованием класса реализовать операции сложения, умножения, деления, сравнения и решения уравнения многочленов.Возникли сложности со всем этим. Могли бы помочь хотя бы что-то реализовать из выше изложенного,пожалуйста
Код:
class Polynom
{
private
int koef;
int stepen;
public
void Sum();
void Multi();
void Divide();
...
}

 Профиль  
                  
 
 
Сообщение30.03.2009, 18:54 
Модератор
Аватара пользователя


11/01/06
5662
Посмотрите как это реализовано, например, в Arageli: http://www.arageli.org/

 Профиль  
                  
 
 
Сообщение31.03.2009, 11:25 


30/09/06
68
Одесса
В классе многочлена нужно использовать указатель на тип float, который будет хранить в себе адрес массива коэффициентов полинома. При этом в конструктор класса обязательно должна передаваться степень полинома, которая и определяет размер массива коэффициентов. В случае отсутствия слагаемого какой-то степени, коэффициент считается равным 0. А следующие действия с таким классом легко проводить. Пробуйте. Будут проблемы спрашивайте.

 Профиль  
                  
 
 
Сообщение09.04.2009, 21:04 


09/09/08
30
Россия
Код:
//polinom.h файл
class polinom
  {
  private:
   int n;    // степень полинома         
    int * a;   // массив для хранения коэффициентов полинома   
  public:
   polinom (int nn);
   polinom (polinom &t);
   ~polinom(void);
   polinom operator+(polinom &t);
   polinom operator*(polinom &t);
   int input(int nn);
   void output(void);
  };
//файл poly.cpp
// реализация методов класса polinom
#include "polinom.h"
polinom::polinom(int nn)
  {
  n=nn;
  a=new int(n);
  for(int i=0;i<=n;i++)
  a[i]=0;
  }
polinom::polinom(polinom&t)
  {
  if(n!=t.n)
  {
  delete a;
  n=t.n;
  a=new int(n);
  }
  for(int i=0;i<=n;i++)
  a[i]=t.a[i];
  }
polinom::~polinom(void)
  {
  delete []a;
  cout<<"polinom udalen";
  }
polinom polinom::operator+(polinom &t)
  {
  if (n>=t.n)
  {polinom temp(n);
  temp.a=new int(n);
  for(int i=0;i<=n;i++)
  temp.a[i]=a[i]+t.a[i];
  return temp;};
  if (n<t.n)
  {polinom temp(t.n);
  for(int i=0;i<=t.n;i++)
  temp.a[i]=a[i]+t.a[i];
  return temp;};
  }

polinom polinom::operator*(polinom &t)
  {
  polinom temp(n+t.n);
  for(int i=0;i<=n;i++)
  {for(int j=0;j<=t.n;j++)
  temp.a[i+j]+=a[i]*t.a[j]; }
  return temp;
  }

int polinom::input(int nn)
  {
  for(int i=0;i<=n;i++)
  a[i]=0;
  n=nn;
  cout<<"vvedite koef.";
  for(int i=0;i<=nn;i++)
  {
  cout<<"a["<<i<<"]=";
  cin>>a[i];
  };
  return 0;
  }
  void polinom::output(void)
  {
  int bb;
  bb=n;
  while(a[bb]==0&&bb>=0)
  bb=bb-1;
  if(bb<0) cout<<"Polinom raven 0"<<endl;
  else{
   if(bb==0) cout<<a[0];
   else{
    cout<<a[bb]<<"x^"<<bb;
    bb=bb-1;
    for(int i=bb;i>0;i--)
     {
      if (a[i]<0) {cout<<a[i];};
      if (a[i]>0) {cout<<"+"<<a[i];};
      if (a[i]!=0) {cout<<"x^"<<i;};
     };
   if (a[0]<0) cout<<a[0];
   if (a[0]>0) cout<<"+"<<a[0];
  }}}

  }
//main.c
void main()
{
   int m;
   int c;
   int nn;
   nn=1;
   polinom q(nn),t(nn);
   do{
clrscr();
cout<<"1.Vvod koef."<<endl;
cout<<"2.Vivod polinoma"<<endl;
cout<<"3.Slozhenie polinomov"<<endl;
cout<<"4.Proizvedenie polinomov"<<endl;
cout<<"5.Vichod"<<endl;
cout<<"Viberete punkt meny"<<endl;
cin>>m;
switch(m)
  {
  case 1:
   {
   cout<<"vvedite stepen'";
   cin>>nn;
   q.input(nn);
   }
   case 2:
   {
   q.output();
   getch();
   break;
   };
  case 3:
   {
  cout<<"vvedite stepen'";
   cin>>nn;
   t.input(nn);
   q=q+t;
   break;
   };
   case 4:
   {
   cout<<"vvedite stepen'";
   cin>>nn;
   t.input(nn);
   q=t*q;
   break;
   };
   case 5:
   {
   exit(1);
    };
  }} while (true);
  }

вот я реализовал часть операций, но умножение работает не всегда(если перемножать полином 1-ой и 4-ой степени какие-то числа с потолка получаются, ну а если перемножать 2-ой и 3-ей или 1-ой степени вроде работает), аналогично и с сложением(не во всех случаях правильно выдает результат).
И осталось реализовать операцию деления не знаю как это сделать может поможете,плиз

 Профиль  
                  
 
 
Сообщение09.04.2009, 22:19 
Заслуженный участник


31/12/05
1485
Moko писал(а):
Код:
  a=new int(n);
  a=new int(n);
Скобки нужны не круглые, а квадратные. Иначе создается не массив, а одна переменная с начальным значением n, и запись в следующие элементы затирает чужую память.
Moko писал(а):
Код:
  {polinom temp(n);
  temp.a=new int(n);
То же самое. К тому же в первой строке при вызове конструктора и так выделяется память под a, зачем делать это еще раз и плодить утечки?

 Профиль  
                  
 
 
Сообщение09.04.2009, 22:44 


30/09/06
68
Одесса
А вы уверены, что эта программа работает? В ней куча логических ошибок при работе с памятью, если она Вам выдает какие-то результаты и не ругается, то это просто повезло

Добавлено спустя 6 минут 59 секунд:

Первое, что необходимо сделать - переделать функцию input(int). Уж коли Вы решили в конструкторе строить массив на один элемент, то в функции input() необходио сначала осводить память, а потом выделить новую нужного размера и только потом запрашивать коэффициенты.
Но лучше в конструкторе делать указатель а равным NULL. Я бы сказала, что это правильнее.

Добавлено спустя 11 минут 39 секунд:

Продолжая мою мысль, хочется сказать, что необходимо при использовании нулевого указателя иметь два конструктора с параметрами и без.

 Профиль  
                  
 
 
Сообщение10.04.2009, 20:18 


09/09/08
30
Россия
Lotos писал(а):
А вы уверены, что эта программа работает? В ней куча логических ошибок при работе с памятью, если она Вам выдает какие-то результаты и не ругается, то это просто повезло

Первое, что необходимо сделать - переделать функцию input(int). Уж коли Вы решили в конструкторе строить массив на один элемент, то в функции input() необходио сначала осводить память, а потом выделить новую нужного размера и только потом запрашивать коэффициенты.
Но лучше в конструкторе делать указатель а равным NULL. Я бы сказала, что это правильнее.

Продолжая мою мысль, хочется сказать, что необходимо при использовании нулевого указателя иметь два конструктора с параметрами и без.

программа вроде компилится выдает результаты. в чем заключаются ошибки? не совсем понял зачем освобождать память потом снова выделять ее? насчет констукторов вы ввели меня в заблуждение. может покажете наглядно два конструктора с параметрами и без, и в чем их отличия?

 Профиль  
                  
 
 
Сообщение11.04.2009, 15:30 


09/09/08
30
Россия
Lotos писал(а):
Первое, что необходимо сделать - переделать функцию input(int). Уж коли Вы решили в конструкторе строить массив на один элемент, то в функции input() необходио сначала осводить память, а потом выделить новую нужного размера и только потом запрашивать коэффициенты.
Но лучше в конструкторе делать указатель а равным NULL. Я бы сказала, что это правильнее.

ну вот в принципе переделал функцию input(), тока не знаю правильно или нет
Код:
int polinom::input(int nn)
  {
  delete []a; // особождаем память
  n=nn;
  a = new int [n]; // выделяем нужного размера
  cout<<"vvedite koef.";
  for(int i=0;i<=nn;i++)
  {
  cout<<"a["<<i<<"]=";
  cin>>a[i];
  };
  return 0;
  }

 Профиль  
                  
 
 
Сообщение12.04.2009, 23:00 


30/09/06
68
Одесса
Теперь подумайте о размере выделяемой памяти под массив а.
(Кстати, Вы исправили круглые скобки на квадратные везде?)
Если полином степени n, то коээфициентов n+1, но тогда и размер массива n+1.
Исправьте все выделения памяти.

Добавлено спустя 2 минуты 6 секунд:

Еще в программе используете оператор присваивания, но Вами он не перегружен.
Проверьте результат сложения, что там? Выведите q.
Хорошо подумайте про конструктор-копировальщик? Для чего он и что делает. Мне он не нравиться.

 Профиль  
                  
 
 
Сообщение13.04.2009, 09:59 


12/04/09
27
Нижний Новгород
Вообще, на какого рода работу рассчитан этот класс? какие ограничения по степени у полиномов?
Просто (присоединяюсь к комментарию Lotos'a) если вы хотите использовать память более экономно, то вам действительно нужно задуматься над конструкторами копирования, оператором присваивания и деструктором.

 Профиль  
                  
 
 
Сообщение13.04.2009, 12:35 


09/09/08
30
Россия
Voodoo Man писал(а):
Вообще, на какого рода работу рассчитан этот класс? какие ограничения по степени у полиномов?

класс расчитан на выполнение операций над полиномами, ограничений по степени полинома нету.
Lotos писал(а):
(Кстати, Вы исправили круглые скобки на квадратные везде?)

Исправил вот что получилось:
Код:
class polinom
{
private:
  int n;   // степень полинома
  int * a; // массив для коэффициентов полинома
public:
  polinom(int nn);      // конструктор
  polinom(const polinom& t);
  ~polinom(void); // деструктор
  polinom operator+(polinom& );
  polinom operator*(polinom&);
  int input(int nn); // ввод
  void output(void); // печать
};
// конструктор
polinom :: polinom(int nn)
{
n=nn;
a=new int[n];
for(int i=0;i<n;++i)
  a[i]=0;
}

polinom::polinom(const polinom& t)
{
  if(n!=t.n)
  {
     delete []a;
     n=t.n;
     a=new int[n];
  }
  for(int i=0;i<n;++i)
  a[i]=t.a[i];
}
// деструктор
polinom::~polinom(void)
{
  delete []a;
}
  // сложение двух полиномов
polinom polinom :: operator+(polinom& t)/*в случае если писать в паараметре (const polinom& t) то пишет ошибку! пробовал писать
polinom polinom :: operator*(const polinom& t) const не помогло*/
{
  if(n>=t.n)
   {
      polinom temp(n);
      for(int i=0;i<n;++i)
      temp.a[i]=a[i]+t.a[i];
      return temp;
   };
  if (n<t.n)
   {
      polinom temp(t.n);
      for(int i=0;i<t.n;++i)
      temp.a[i]=a[i]+t.a[i];
      return temp;
   };
}
// произведение полиномов
polinom polinom :: operator*(polinom& t)
{
  polinom temp(n+t.n);
  for (int i = 0; i < n; ++i)
   {
      for (int j = 0; j <t.n ; ++j)
      {
       temp.a[i+j]+=a[i]*t.a[j];
         }
   }
  return temp;
}
// ввод полинома
int polinom::input(int nn)
{
  delete[]a;
  n=nn;
  a =  new int [n];
  printf("Input koeff :\n");
  for(int i=0;i<n;++i)
  {
     printf("a[%d] = ",i);
     scanf("%d",&a[i]);
  };
  return 0;
};
// печать полинома
void polinom::output(void)
{
   int bb;
   bb=n;
   while(a[bb]==0&&bb>=0)
   bb=bb-1;
   if(bb<0) printf("Polinom raven 0");
   else
   {
      if(bb==0) printf("%d",a[0]);
      else
      {
         printf("%dx^%d",a[bb],bb);
         bb=bb-1;
         for(int i=bb;i>0;i--)
         {
            if (a[i]<0)
            {
               printf("%d",a[i]);
            };
            if (a[i]>0)
            {
               printf("+%d",a[i]);
            };
            if (a[i]!=0)
            {
               printf("x^%d",i);
            };
         };
         if (a[0]<0) printf("%d",a[0]);
         if (a[0]>0)
            {
               printf("+%d",a[0]);
            }
         }
   }
}
int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    int nn;
    nn=1;
    polinom a(nn),b(nn),c(nn);
    printf("Input degree for Polynom_1 = ");
    scanf("%d",&nn);
    a.input(nn);
    printf("Polynom_1 = ");
    a.output();
    printf("Input degree for Polynom_2 = ");
    scanf("%d",&nn);
    b.input(nn);
    printf("Polynom_2 = ");
    b.output();
    c=a+b;
    printf("Sum polynom is = \n");
    c.output();
}

но все равно не работает как надо. но теперь после того как переделал условие в цикле for(int i = 0; i<n; ++i) на строгое неравенсто i<n,при вводе полинома например 2-ой степени он запрашивает коэфф. a[0] и a[1], т.е. получается
полином не 2-ой степени,а как бы первой(2x^1+5).может вызов конструктора неправильный у меня ?
посмотрите что не так?

 Профиль  
                  
 
 
Сообщение13.04.2009, 13:22 


30/09/06
68
Одесса
Я написала, что надо исправить выделение памяти, а не циклы!
Условия циклов верните обратно, а везде, где идет выделения с оператором new, надо писать в квадратных скобках [n+1]

Добавлено спустя 6 минут 40 секунд:

А куда пропала функция оператора суммирования?
Верните ее, с ней надо просто поработать:
1. Уберите команду
temp.a=new int[n];
2. Если полиномы разной степени, то часть коээфициентов складывается при одинаковых степенях, а чсть перегоняется из того полинома, у которого степень выше.

 Профиль  
                  
 
 
Сообщение13.04.2009, 13:45 


09/09/08
30
Россия
Код:
//polinom.h файл
class polinom
  {
  private:
   int n;    // степень полинома         
    int * a;   // массив для хранения коэффициентов полинома   
  public:
   polinom (int nn);
   polinom (polinom &t);
   ~polinom(void);
   polinom operator+(polinom &t);
   polinom operator*(polinom &t);
   int input(int nn);
   void output(void);
  };
//файл poly.cpp
// реализация методов класса polinom
#include "polinom.h"
polinom::polinom(int nn)
  {
  n=nn;
  a=new int[n+1];
  for(int i=0;i<=n;i++)
  a[i]=0;
  }
polinom::polinom(polinom&t)
  {
  if(n!=t.n)
  {
  delete []a;
  n=t.n;
  a=new int[n+1];
  }
  for(int i=0;i<=n;i++)
  a[i]=t.a[i];
  }
polinom::~polinom(void)
  {
  delete []a;
  }
polinom polinom::operator+(polinom &t)
  {
  if (n>=t.n)
  {polinom temp[n+1];
  for(int i=0;i<=n;i++)
  temp.a[i]=a[i]+t.a[i];
  return temp;};
  if (n<t.n)
  {polinom temp[n+1];
  for(int i=0;i<=t.n;i++)
  temp.a[i]=a[i]+t.a[i];
  return temp;};
  }

polinom polinom::operator*(polinom &t)
  {
  polinom temp[n+t.n+1];// здесь ПРАВИЛЬНО???
  for(int i=0;i<=n;i++)
  {for(int j=0;j<=t.n;j++)
  temp.a[i+j]+=a[i]*t.a[j]; }
  return temp;
  }

int polinom::input(int nn)
  {
  n=nn;
  delete []a;
  a=new int[n+1];
  cout<<"vvedite koef.";
  for(int i=0;i<=nn;i++)
  {
  cout<<"a["<<i<<"]=";
  cin>>a[i];
  };
  return 0;
  }
  void polinom::output(void)
  {
  int bb;
  bb=n;
  while(a[bb]==0&&bb>=0)
  bb=bb-1;
  if(bb<0) cout<<"Polinom raven 0"<<endl;
  else{
   if(bb==0) cout<<a[0];
   else{
    cout<<a[bb]<<"x^"<<bb;
    bb=bb-1;
    for(int i=bb;i>0;i--)
     {
      if (a[i]<0) {cout<<a[i];};
      if (a[i]>0) {cout<<"+"<<a[i];};
      if (a[i]!=0) {cout<<"x^"<<i;};
     };
   if (a[0]<0) cout<<a[0];
   if (a[0]>0) cout<<"+"<<a[0];
  }}}

  }
//main.c
void main()
{
   int m;
   int c;
   int nn;
   nn=1;
   polinom q(nn),t(nn);
   do{
clrscr();
cout<<"1.Vvod koef."<<endl;
cout<<"2.Vivod polinoma"<<endl;
cout<<"3.Slozhenie polinomov"<<endl;
cout<<"4.Proizvedenie polinomov"<<endl;
cout<<"5.Vichod"<<endl;
cout<<"Viberete punkt meny"<<endl;
cin>>m;
switch(m)
  {
  case 1:
   {
   cout<<"vvedite stepen'";
   cin>>nn;
   q.input(nn);
   }
   case 2:
   {
   q.output();
   getch();
   break;
   };
  case 3:
   {
  cout<<"vvedite stepen'";
   cin>>nn;
   t.input(nn);
   q=q+t;
   break;
   };
   case 4:
   {
   cout<<"vvedite stepen'";
   cin>>nn;
   t.input(nn);
   q=t*q;
   break;
   };
   case 5:
   {
   exit(1);
    };
  }} while (true);
  }

ну от вроде исправил, так?

 Профиль  
                  
 
 
Сообщение13.04.2009, 20:26 


30/09/06
68
Одесса
Лихо! Вы даже в объявлении локальных объектов temp умудрились поставить квадратные скобки.

Добавлено спустя 2 минуты 24 секунды:

Квадратные скобки ставятся, когда выделяется динамическая память с помощью оператора new.
Круглые скобки ставятся при объявлении объекта класса для вызова конструктора с входящими параметрами.
Это совершенно разные действия.

Добавлено спустя 4 минуты 43 секунды:

Зачем изменили объявление объекта temp в операторе умножения?
Верните прежнее.

Добавлено спустя 3 минуты 28 секунд:

Не хватайтесь за весь код сразу. Надо сделать рабочими сначала функцию суммирования, а так как результат Вы присваиваиваете с помощью оператора присваивания, то перегрузите его.

Добавлено спустя 3 минуты 40 секунд:

Да и почитайте про копировальщик, когда он вызывается и зачем?
Читайте выше, что я писала про суммирование полиномов

 Профиль  
                  
 
 
Сообщение13.04.2009, 21:21 


09/09/08
30
Россия
Код:
class polinom
{
private:
  int n;  // степень полинома
  int * a;   // массив коэффициентов
public:
  polinom(int nn);   // конструктор
  polinom(const polinom&t);
  ~polinom(void);       // деструктор
  polinom operator+(polinom &);
  polinom operator*(polinom &);
  polinom &operator=(const polinom &t); // присваивание
  int input(int nn);  // ввод полинома
  void output(void);  // печать полинома
};
// конструктор
polinom :: polinom(int nn)
{
n=nn;
a=new int[n+1];
for(int i=0;i<=n;++i)
  a[i]=0;
}
polinom::polinom(const polinom&t)
{
  if(n!=t.n)
  {
     delete []a;
     n=t.n;
     a=new int[n+1];
  }
  for(int i=0;i<=n;i++)
  a[i]=t.a[i];
}
// деструктор
polinom::~polinom(void)
{
  delete []a;
}
// сложение двух полиномов
polinom polinom::operator+(polinom&t)
{
  if(n>=t.n)
   {
      polinom temp(n);
      for(int i=0;i<=n;i++)
      temp.a[i]=a[i]+t.a[i];
      return temp;
   };
  if (n<t.n)
   {
      polinom temp(t.n);
      for(int i=0;i<=t.n;i++)
      temp.a[i]=a[i]+t.a[i];
      return temp;
   };
}
// произведение полиномов
polinom polinom :: operator*(polinom&t)
{
  polinom temp(n+t.n);
  for (int i = 0; i <= n; i++)
   {
      for (int j = 0; j <=t.n ; j++)
      {
         temp.a[i+j]+=a[i]*t.a[j];
         }
   }
  return temp;
}

// присваивание полиномов. правильно??
polinom& polinom :: operator=(const polinom &t)
{
if(n>t.n)
  {
  for (int i=t.n;i<=n;i++)
  a[i]=0;
  }
  n=t.n;
  for(int i=0;i<=n;i++)
  a[i]=t.a[i];
  return *this;
}
// ввод полинома
int polinom::input(int nn)
{
  n=nn;
  delete []a;
  a = new int[n+1];
  printf("Input koeff :\n");
  for(int i=0;i<=nn;i++)
  {
     printf("a[%d] = ",i);
     scanf("%d",&a[i]);
  };
  return 0;
};
// печать полинома
void polinom::output(void)
{
   int bb;
   bb=n;
   while(a[bb]==0&&bb>=0)
   bb=bb-1;
   if(bb<0) printf("Polinom raven 0");
   else
   {
      if(bb==0) printf("%d",a[0]);
      else
      {
         printf("%dx^%d",a[bb],bb);
         bb=bb-1;
         for(int i=bb;i>0;i--)
         {
            if (a[i]<0)
            {
               printf("%d",a[i]);
            };
            if (a[i]>0)
            {
               printf("+%d",a[i]);
            };
            if (a[i]!=0)
            {
               printf("x^%d",i);
            };
         };
         if (a[0]<0) printf("%d",a[0]);
         if (a[0]>0)
            {
               printf("+%d",a[0]);
                }
         }
   }
}
// main.c
void inputpolinoms(polinom &a, polinom &b)
{
   int nn;
   printf("Input degree for Polynom_1 = ");
   scanf("%d",&nn);
   a.input(nn);
   printf("Polynom_1 = ");
   a.output();
   printf("Input degree for Polynom_2 = ");
   scanf("%d",&nn);
   b.input(nn);
   printf("Polynom_2 = ");
   b.output();
}
int _tmain(int argc, _TCHAR* argv[])
{
   int i;
   int nn;
   nn=1;
   polinom a(nn),b(nn),c(nn);
   inputpolinoms(a,b);
   c=a+b;
   printf("Sum polynom is = ");
   c.output();
}

ну вот переделал с учетом замечаний. Перегрузил оператор присваивания вроде проверял работает, а программа в целом не хочет работать :(

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Schrodinger's cat


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group