Разреженная квадратная матрица (Delphi 7)
Может кто-то имеет представление как решить эту задачу, помогите, пожалуйста...очень нужна эта задачка...спасибо.
Задание звучит так:
«Разработать класс разреженная квадратная матрица ( разреженная матрица это матрица высокого порядка с большим количеством нулевых элементов ). Для представления разреженной матрицы использовать двусвязный циклический список. Каждое звено списка состоит из пяти полей :
• поле с номером строки ненулевого элемента,
• поле с номером столбца ненулевого элемента,
• поле со значением элемента,
• поле со ссылкой на предыдущий ненулевой элемент в этой же строке,
• поле со ссылкой на предыдущий ненулевой элемент в этом же столбце.
Каждая строка ( и столбец ) имеют заглавное звено, соответствующее ссылочное поле которого содержит ссылку на последний ненулевой элемент в строке ( в столбце ).
(Delphi 7.0)»
Заранее спасибо.
Учить си++, тогда и все получицо
Сильное утверждение, во что с трудом вериться(кто знает, тот все может сделать).
Хай. значит так:
1)читаешь как реализовать самый простейший класс. с этим даже первокурсники справятся. по сути - та же структура, которую ты без проблем напишешь, если знаешь С.
2)идешь на вику и читаешь, как реализуется связной\связанный\двусвязный(а черт его знает, как правильно. кажется, последний вариант). там точно должны быть примеры. разбери алгоритм и напиши его на сишке. могу посоветовать, ну Шилдта(не айс, конечно, но других счас не помню более-менее понятных реализаций).
3) делаешь несколько практических примеров списков на С++ с объектами. ну, там, карусельку какую или еще что простенькое.
4)???
5)PROFIT!
мастера-программисты!
в доказательство того, что все посоветонное Alm3n'ом я прошла и по нескольку раз, приведу программу, где почему-то 2 компиллятора Visual Studio 2008 и Builder 6 виснут на деструкторе. Первоначально я думала что проблема в том как вычисляется инртеграл и/или производная, но кажется ошибалась((( Помогите, раз вы Седжвика наизусть знаете. И еще никак не могу у него №4.11 решить(
а про мультисписки - это оттуда же задача из Седжвика(д/справки, №3.67), и если вы ее с легкостью решаете - то уважаю!!!
вот тот злополучный код(без плагиата,не считая нескольких строчек Седжвика,все сама написала!):
#ifndef _POLY_
#define _POLY_
#include <iostream>
template<class Number>class Poly{
private:
int N,M;
Number* a;
public:
Poly(Number c,int _N,int _M):M(_M+1){
a=new Number[_N+1];
N=_N+1;
a[_N]=c;
for (int i=0;i<_N;++i)a=0;
}//constructor
~Poly(){
if (a)delete[]a;
}//destructor
Poly(const Poly&p){
a=0;
*this=p;
}//copy constructor
Poly& operator =(const Poly&p){
if (this==&p)return *this;
if (a)delete[]a;
N=p.N;
a=new Number[N];
for (int i=0;i<M;++i)a=p.a;
for (int i=M;i<N;++i)a=0;
return *this;
}//operator =
Number evaluate(Number x)const{
Number t=0;
for (int i=M-1;i>=0;--i)t=t*x+a;
return t;
}//evaluate
friend Poly operator +(Poly&p1,Poly&p2){
Poly t(0,p1.N>p2.N?p1.N-1:p2.N-1,p1.M>p2.M?p1.M-1:p2.M-1);
for (int i=0;i<p1.M;++i)t.a+=p1.a;
for (int j=0;j<p2.M;++j)t.a[j]+=p2.a[j];
for (int i=M;i<N;++i)a=0;
return t;
}//operator +
friend Poly operator -(Poly&p1,Poly&p2){
Poly t(0,p1.N>p2.N?p1.N-1:p2.N-1,p1.M>p2.M?p1.M-1:p2.M-1);
for (int i=0;i<p1.M;++i)t.a+=p1.a;
for (int j=0;j<p2.M;++j)t.a[j]-=p2.a[j];
for (int i=M;i<N;++i)a=0;
return t;
}//operator -
friend Poly operator *(Poly&p1,Poly&p2){
Poly t(0,(p1.N-1)+(p2.N-1),(p1.M-1)+(p2.M-1));
for (int i=0;i<p1.N;++i)
for (int j=0;j<p2.N;++j)t.a[i+j]+=p1.a*p2.a[j];
for (int i=M;i<N;++i)a=0;
return t;
}//operator *
friend std::ostream& operator << (std::ostream&os,Poly<Number>&p){
for (int i=p.N-1;i>=0;--i){
if (i!=p.N-1&&p.a>=0)os << "+";
os << p.a << "x^" << i;
}
return os;
}//operator <<
friend std::istream& operator >> (std::istream&is,Poly<Number>&p){
for (int i=p.N-1;i>=0;--i)is >> p.a;
return is;
}//operator >>
Poly& operator +=(Poly&p){
Poly t(0,N>p.N?N-1:p.N-1);
for (int j=0;j<p2.N;++j)t.a[j]+=p2.a[j];
*this=t;
return *this;
}//operator +=
Poly& operator *=(Poly&p){
Poly t(0,(N-1)+(p.N-1));
for (int i=0;i<N;++i)
for (int j=0;j<p.N;++j)t.a[i+j]+=a*p.a[j];
*this=t;
return *this;
}//operator *=
Poly derivative(){
Poly p(0,N-2);
for (int i=N;i>0;i--)p.a[i-1]=i*a;
return p;
}//derivative
Poly integral(){
Poly p(0,N);
//for (int i=N;i>=0;--i)p.a[i+1]=a/(i+1);
p.a[0]=0;
return p;
}//integral
};//class Poly
#endif /* _POLY_ */
//file main.cpp
#include <iostream>
#include <cstdlib>
#include "poly.h"
using namespace std;
int main(){
int N;
cin >> N;
Poly<double>p(0,N,N);
cin >> p;
cout << p << endl;
Poly<double>pd=p.derivative();
cout << pd << endl;
Poly<double> pi=p.integral();
cout << pi << endl;
cout << (pi=pi-pd) << endl;
system("pause");
return 0;
}
Представляет полином со всеми операциями, которые с ним можно совершать. =)
в смысле непонятный или слишком сложный код?
В общем, не нужно в нем во всем разбираться, только скопировать в проект какого-нибудь С++-компиллятора и тогда увидите ЧТО он выдает и может - надеюсь! - кого озарит как это исправить))
не совсем со всеми, я так и не смогла сделать деление многочленов((
Poly t(0,p1.N>p2.N?p1.N-1:p2.N-1,p1.M>p2.M?p1.M-1:p2.M-1);
for (int i=0;i<p1.M;++i)t.a+=p1.a;
for (int j=0;j<p2.M;++j)t.a[j]+=p2.a[j];
for (int i=M;i<N;++i)a=0;
return t;
Poly t(0,N>p.N?N-1:p.N-1);
for (int j=0;j<p2.N;++j)t.a[j]+=p2.a[j];
*this=t;
return *this;
Poly p(0,N-2);
for (int i=N;i>0;i--)p.a[i-1]=i*a;
return p;
}//derivative
1,2 либо сделать члены константными, либо указывать к какому объекту они относятся.
3 нет такого конструктора.
и теги никакие внутри code не работают, почему-то.
Что же касается объявления операторов, то с ними вроде проблем никаких нет...
Вот код заново, но интеграл все равно не считает, виснет (выдает стек вызовов, ниже)
private:
int N;
Number* a;
public:
Poly(Number c,int _N){
a=new Number[_N+1];
N=_N+1;
a[_N]=c;
for (int i=0;i<_N;++i)a=0;
}//constructor
~Poly(){
if (a) delete[]a; //This not works!!!
}//destructor
Poly(const Poly&p){
a=0;
*this=p;
}//copy constructor
Poly& operator =(const Poly&p){
if (this==&p)return *this;
if (a)delete[]a;
N=p.N;
a=new Number[N];
for (int i=0;i<N;++i)a=p.a;
return *this;
}//operator =
Number evaluate(Number x)const{
Number t=0;
for (int i=N-1;i>=0;--i)t=t*x+a;
return t;
}//evaluate
friend Poly operator +(Poly&p1,Poly&p2){
Poly t(0,p1.N>p2.N?p1.N-1:p2.N-1);
for (int i=0;i<p1.N;++i)t.a+=p1.a;
for (int j=0;j<p2.N;++j)t.a[j]+=p2.a[j];
return t;
}//operator +
friend Poly operator *(Poly&p1,Poly&p2){
Poly t(0,(p1.N-1)+(p2.N-1));
for (int i=0;i<p1.N;++i)
for (int j=0;j<p2.N;++j)t.a[i+j]+=p1.a*p2.a[j];
return t;
}//operator *
friend std::ostream& operator << (std::ostream&os,Poly&p){
for (int i=p.N-1;i>=0;--i){
if (i!=p.N-1&&p.a>=0)os << "+";
os << p.a << "x^" << i;
}
return os;
}//operator <<
friend std::istream& operator >> (std::istream&is,Poly&p){
for (int i=p.N-1;i>=0;--i)is >> p.a;
return is;
}//operator >>
Poly& operator +=(Poly&p){
Poly t(0,N>p.N?N-1:p.N-1);
for (int j=0;j<p2.N;++j)t.a[j]+=p2.a[j];
*this=t;
return *this;
}//operator +=
Poly& operator *=(Poly&p){
Poly t(0,(N-1)+(p.N-1));
for (int i=0;i<N;++i)
for (int j=0;j<p.N;++j)t.a[i+j]+=a*p.a[j];
*this=t;
return *this;
}//operator *=
Poly derivative(){
Poly p(0,N-2);
for (int i=N;i>0;i--)p.a[i-1]=i*a;
return p;
}//derivative
Poly integral(){
Poly p(0,N);
for (int i=N;i>=0;--i)p.a[i+1]=a/(i+1);
p.a[0]=0;
return p;
}//integral
Стек вызовов:
ntdll.dll!7c919ba0()
kernel32.dll!7c80adde()
//здесь немного пропущено, но это не важно, главное, что// проблема в операторе delete[], но почему - не знаю(((
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x00336158, int nBlockUse=1) Строка 1371 + 0x33 байт C++
msvcr90d.dll!_free_dbg(void * pUserData=0x00336158, int nBlockUse=1) Строка 1258 + 0xd байт C++
msvcr90d.dll!operator delete(void * pUserData=0x00336158) Строка 54 + 0x10 байт C++
msvcr90d.dll!operator delete[](void * p=0x00336158) Строка 21 + 0x9 байт C++
divnrule_algo.exe!Poly<int>::~Poly<int>() Строка 17 + 0x21 байт C++
> divnrule_algo.exe!Poly<int>::integral() Строка 81 + 0x27 байт C++
divnrule_algo.exe!main() Строка 46 + 0x17 байт C++
divnrule_algo.exe!__tmainCRTStartup() Строка 582 + 0x19 байт C
divnrule_algo.exe!mainCRTStartup() Строка 399 C
kernel32.dll!7c816fd7()
Потому, что конструктор копирования написан соотв. образом.
Но даже если переделать конструктор копирования(вот так:
N=p.N;
a=new Number[N];
for (int i=0;i<N;++i)a=p.a;
}//copy constructor
)то все равно те же проблемы((((
"CRT detected that the application wrote to memory after end of heap buffer.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead));
И да, действительно вы в своем коде заходите за границы выделенной памяти, например здесь:
Poly integral(){
Poly p(0,N);
for (int [COLOR="red"]i=N[/COLOR];i>=0;--i)p.a[[COLOR="red"]i+1[/COLOR]]=a/(i+1);
p.a[0]=0;
return p;
}//integral
На будущее предоставляйте пожалуйста и код в котором используете свои классы.
PS: Раз уж зашел разговор о коде, он у вас мусорный, не exception-safe и не портабельный.
Poly integral(){
Poly p(0,N);
for (int i=N;i>=0;--i)p.a[i+1]=a/(i+1);
p.a[0]=0;
return p;
}//integral
Спасибо огромное!!!!:)Такая глупая ошибка, а сколько проблем!
просто я не предполагала что там ошибки(да еще такие глупые)будут, и придется просить помощи))