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, Супермодераторы



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

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


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

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