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
5702
Посмотрите как это реализовано, например, в 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
1516
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, Супермодераторы



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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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