2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 
Сообщение13.04.2009, 22:32 


30/09/06
68
Одесса
Вы не реализовали идею суммирования полиномов, о которой я Вам писала. Вот код этой функции (если будут проблемы с переменной счетчиком объявите еще раз в цикле)
Код:
polinom polinom::operator+(polinom &t)
  {
  if (n>=t.n)
  {polinom temp(n);
   for(int i=0;i<=t.n;i++)
  temp.a[i]=a[i]+t.a[i];
   for(i=t.n+1;i<=n;i++)
      temp.a[i]=a[i];
  return temp;};
  if (n<t.n)
  {polinom temp(t.n);
  for(int i=0;i<=n;i++)
  temp.a[i]=a[i]+t.a[i];
  for( i=n+1;i<=t.n;i++)
  temp.a[i]=t.a[i];
  return temp;};
  }

 Профиль  
                  
 
 
Сообщение14.04.2009, 10:49 


09/09/08
30
Россия
реализовал данное суммирование, но теперь программа работает только если складывать полиномы одинаковых степеней, в противном случае выдает неправильный результат.
я думаю может ошибка в передаче параметра, т.е. надо делать так
Код:
polinom polinom::operator+(const polinom &t)
? но в этом случае программа не компилится пишет ошибку
Unresolved external 'polinom::operator+(polinom &t)' referenced from C:\...\FILE.OBJ

 Профиль  
                  
 
 
Сообщение14.04.2009, 13:18 


30/09/06
68
Одесса
Ваша проблема в том, что Вы не понимаете сущность используемого синтаксиса.
Служебное слово const используется для передачи неизменного объекта, т.е. величины постоянной. Вам оно совершенно не надо, а ошибка компилятора связана с тем, что слово const является частью сигнатуры функции, а Вы явно пишите его только при определении функции, а в объявлении забыли написать.
Функция оператора суммирования правильная и работает с полиномами разных степеней в любом порядке, но вы не понимаете, что у вас при присваивании копия объекта temp, возвращаемая из оператора суммирования с помощью оператора присваивания загоняется в полином не всегда нужной степени.
Код:
c=a+b;

Какая степень у с?

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

А Вы знаете, что когда возвращается объект temp из оператора суммирования, то создается его копия с помощью копировальщика?
Копировальщик у Вас не рабочий. Я уже несколько раз об этом пишу. Он должен иметь вид:
Код:
polinom::polinom(polinom&t)
  {
   n=t.n;
   a=new int [n+1];   
  for(int i=0;i<=n;i++)
  a[i]=t.a[i];
  }


Вставляйте и думайте про суммирование еще раз. Успехов. :D

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


09/09/08
30
Россия
Lotos писал(а):
а ошибка компилятора связана с тем, что слово const является частью сигнатуры функции, а Вы явно пишите его только при определении функции, а в объявлении забыли написать.

нет я писал его и в объявлении функции, просто я не стал помещать сюда то что я изменил в объявлении это же очевидные вещи. а ошибку все равно писал, ну да ладно с этой ошибкой.
Lotos писал(а):
А Вы знаете, что когда возвращается объект temp из оператора суммирования, то создается его копия с помощью копировальщика?

Да я это знаю. насчет того что он был не рабочий это я подозревал.
буду пробывать тестить.скоро отпишусь

Добавлено спустя 2 часа 50 минут 57 секунд:

суммирование опять не работает!практически ничего не изменилось с изменением копировальщика.
иногда даже программа вылетает "Access Violation" в этом месте
Код:
int polinom::input(int nn)
{
  n=nn;
  delete []a;// ВОТ ЗДЕСЬ!!!
  a = new int[n+1];
....

и в деструкторе
Код:
polinom::~polinom(void)
{
  delete []a;//!!!
}

а вы уверены что надо при выделении памяти делать n+1?? мне кажется тогда в циклах надо заменить условие на строгое неравенсто i<n.
что насчет произведения, то на мое удивление работает практически без сбоев,после закрытия ехе-шника вылетает все таже "Access Violation" в месте
где реализован деструктор (см. выше).как устранить эту ошибку?
а с суммированием даже не знаю что и делать :(

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


30/09/06
68
Одесса
У вас каким-то образом получаются блуждающие указатели. Вот ваш код с моего компа, который не умирает, но он не переделанный полностью, а только с частичными изменениями.
Запустите у себя, интересно, что будет.
Код:
#include <iostream.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);
   polinom & operator=(polinom t);
   int input(int nn);
   void output(void);
   int GetN(){return n;}
  };
//ôàéë 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)
  {
   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;
  cout<<"polinom udalen";
  }

polinom polinom::operator+(polinom &t)
  {
  if (n>=t.n)
  {polinom temp(n);
   for(int i=0;i<=t.n;i++)
  temp.a[i]=a[i]+t.a[i];
   for(i=t.n+1;i<=n;i++)
      temp.a[i]=a[i];
  return temp;};
  if (n<t.n)
  {polinom temp(t.n);
  for(int i=0;i<=n;i++)
  temp.a[i]=a[i]+t.a[i];
  for( i=n+1;i<=t.n;i++)
  temp.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 =(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)
  {
  delete []a; // îñîáîæäàåì ïàìÿòü
  n=nn;
  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<<"\n";
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);
   int k;
   if(q.GetN()>t.GetN())
      k=q.GetN();
   else
      k=t.GetN();
   polinom my(k);
   my=q+t;
   my.output();
   break;
   };
   case 4:
   {
   cout<<"vvedite stepen'";
   cin>>nn;
   t.input(nn);
   q=t*q;
   break;
   };
   case 5:
   {
//   exit(1);
      return;
    };
  }} while (true);
  }

Пробуйте

 Профиль  
                  
 
 
Сообщение15.04.2009, 02:52 


26/02/06
78
Russia, Nizhny Novgorod
Вот это:
Код:
  delete []a;// ВОТ ЗДЕСЬ!!!
  a = new int[n+1];

--- ужаснейшая идея из возможных. Тему с начала не читал, но возникло ощущение, что в работе с динамической памятью вы не профессионал. А раз так, надо не мучиться и использовать vector<int> a; из STL и все проблемы уйдут.

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


09/09/08
30
Россия
все проверил, теперь работает(спасибо за исправленный код), тока у вас была ошибка:) зачем вы закомментировали в
Код:
polinom & polinom::operator =(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;
}

вообщем сложение и произведение заработало.вы мне не ответили на вопрос зачем при выделении памяти мы делаем n+1?
и осталось последнее самое тяжелое реализовать операцию деления полиномов.я как понимаю перегружать оператор деления уже нельзя?!поэтому надо писать функцию
friend bool divide (polinom &a,polinom&b,polinom &res,polinom&ostatok); так выходит?правильные параметры?

 Профиль  
                  
 
 
Сообщение15.04.2009, 20:37 


12/04/09
27
Нижний Новгород
ZYV писал(а):
надо не мучиться и использовать vector<int> a; из STL и все проблемы уйдут.

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

Moko, почитайте "Объектно-ориентированное программирование в С++" Р. Лафоре. Там приведён пример "самопального" класса строк, который экономно использует память. Некоторые идеи, которыеи излагает автор, вполне применимы и для вашего класса полиномов.

 Профиль  
                  
 
 
Сообщение15.04.2009, 22:56 


26/02/06
78
Russia, Nizhny Novgorod
Voodoo Man
И сколько миллисекунд и байт мы на этом теряем? Давайте писать в машинных кодах - этот ООП навесок - ужасно жруч на всё, что только можно...

Ключевой вопрос - это зачем пишется этот класс. Если, например, это учебная задачка, то никакого смысла заморачиваться такими вопросами нету, надо делать так, чтобы было просто, удобно и понятно. А это значит, что надо не стесняясь пользоваться всеми удобствами STL. На то она и нужна.

 Профиль  
                  
 
 
Сообщение16.04.2009, 12:20 


09/09/08
30
Россия
я понимамаю что так проще и легче, но дело в том что задачу в этом случае у меня не примут. Смысл в этой задаче это показать работу с классами! вот поэтому пишется этот класс

 Профиль  
                  
 
 
Сообщение16.04.2009, 12:25 


30/09/06
68
Одесса
1. Память выделяется под n+1 элемент, так как n+1 коэффициент в полиноме степени n.
2. Я не смотрела оператор умножения. Думаю имеется некорректный алгоритм с точки зрения математики, а не только информатики, хотя могу и ошибаться, особо не рассматривала код.
3. В операторе присваивания закоментрирована строка
Код:
n=t.n;

так как выполнение команды такого вида приводит к тому, что полином слева получает степень t.n, при этом под его указатель была выделена память размера n+1. Вообще логичнее было делать проверку, что оператор присваивания работает только для полиномов одинаковой степени.

Народ не понимает, что за задачу решаем. Я думаю, что это просто лаба по программированию.;

 Профиль  
                  
 
 
Сообщение16.04.2009, 12:56 


09/09/08
30
Россия
да вы правы это лаба по программированию :)
а можно перегружать оператор сравнения ">" если мне надо сравнить два полинома?
Код:
polinom polinom :: operator>(polinom &t)

и что он должен возвращать в качестве результата просто сообщение, да?
или надо написать булевскую функцию?
Код:
bool PolyIsEqual( polinom &p, polinom &q )
{
    if ( p.n != q.n ) return FALSE;
    for (int i = 0; i <= p.n; i++ )
        if ( p.a[i] != q.a[i] ) return FALSE;
    return TRUE;
}

как будет выглядеть операция сравнения кто есть больше?

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

Код:
bool PolyIsGrow(polinom &p,polinom &q)
{
if (p.n>q.n) return TRUE;
if (p.n=q.n)
{
for (int i=a.n; i>=0; i--)
if (p.a[i]>q.a[i]) return TRUE;
return FALSE;
}
}

это наверное неправильно?

 Профиль  
                  
 
 
Сообщение16.04.2009, 13:35 


26/02/06
78
Russia, Nizhny Novgorod
Moko писал(а):
я понимамаю что так проще и легче, но дело в том что задачу в этом случае у меня не примут. Смысл в этой задаче это показать работу с классами! вот поэтому пишется этот класс


Меня удивляет, что прежде чем отвечать мне, вы даже не потрудились посмотреть, о чем собственно идет речь, и, соответственно, написали какую-то несусветицу. Я говорю о том, чтобы заменить динамическое выделение памяти и работу с указателями, с которыми вы работать не умеете и поэтому ваша программа падает с ошибками доступа к невыделенной памяти, на использование простого и понятного класса STL vector, думать о котором можно как о динамическом массиве, который сам умеет расширять и сужать себя, если надо и не требует ручной работы с указателями:

http://www.cplusplus.com/reference/stl/vector/

В частности, понятный пример использования тут:

http://www.cplusplus.com/reference/stl/ ... tor%5B%5D/

Конкретно в вашем случае это использование выразится, в том, что надо будет убрать int n и использовать вместо него a.size();, а также убрать int * a; и сделать vector<int> a; а в конструкторе класса сделать a.resize(nn);

Таким образом, вы не только продемонстрируете, что вы умеете сами писать классы, но и то, что вы знаете классы стандартной библиотеки Си и понимаете, как их грамотно использовать.

 Профиль  
                  
 
 
Сообщение16.04.2009, 13:48 


09/09/08
30
Россия
могли бы показать конкретный пример на какой-то одной функции из кода выше как это будет выглядеть.

 Профиль  
                  
 
 
Сообщение16.04.2009, 14:24 


30/09/06
68
Одесса
Я писала о примитивном сравнении по степени без оператора, но если вам нравится - пишите перегруженный оператор, но он должен принимать только правый операнд, как и все.Вы же написали просто функцию сравнения полиномов.

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

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



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

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


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

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