a class of polynomials, errors

hey there,
i wanna write a class for polynomials, but there are some bugs in my code and since im a beginner in programming, so i cant find it by myself.

i want to identify a polynomial with two arrays of the same length, one that contains the exponents of the nonzero monomials, and the other that contains the coefficients itself.

for example: (shematically)
3x^2 +5x^100 shoud be identified by array1=(2,100) and array2=(3,5)

the size of that polynomial should be Dim=2.
it should be possible to change the size dynamically.

know here is the code ive written yet:

#ifndef poly
#define poly
#include<cassert>


class poly
{


public:
//constructor
poly(int x);

//copy constructor
poly(const poly float& v); //kopierkonstruktor

//destructor
virtual ~poly() {delete [] start;delete [] koef;} //destruktor

//asks for the size
int size() const {return xDim;}//fragt die groesse ab

//changes the size
void changesize(int); //dynamisch aerndert die groesse

//indexoperator
float& operator[](int index)
{
assert(index >= 0 && index < xDim);
return start[index];
}

//zuweisungs-operator
poly float& operator=(const poly float&);

void init(const float&);

float* begin1() {return start;}
float* end1() {return start +xDim;}
const float* begin1() const {return start;}
const float* end1() const{ return start +xDim;}


float* begin2() {return koef;}
float* end2() {return koef +xDim;}
const float* begin2() const {return koef;}
const float* end2() const{ return koef +xDim;}

protected:
int xDim;
float *start,*koef;
};

poly::poly(int x=0)
:xDim(x), start(new float[x]), koef(new float[x])
{}


inline poly::poly(const poly float &v) //kopierkonstruktor
{
xDim =v.xDim;
start = new T[xDim];
for(int i=0; i<xDim;i++)
{
start[i]=v.start[i];
koef[i]=v.koef[i];
}
}

//initialisierung von polynomen:

template<class T>
inline void poly<T>::init(const T& wert, const T&kwert)
{
for(int i = 0; i<xDim; i++)
start[i]=wert;
koeff[i]=kwert;
}
#endif

PROBLEM1 the destructor isnt working:
virtual ~poly() {delete [] start;delete [] koef;} //destruktor
Error: This declaration has no Storage class or typ specifier.
Error: Expected an identifier.

PROBLEM2 the constructor isnt working:
poly::poly(int x=0)
Error: Expected an identifier
Error: Expected a )
Error: Expected a ;.

I dont know what the computer want to tell me??

if there is somebody understands this errors, please help me to fix them!

greetings rasputinxiaoshitou
A couple things.

First, is this a template class or not? The init definition hints that it might be, but nothing else supports that.

Secondly, why are you trying to dynamically allocate 2 arrays and keep them the same size? Instead of 2 parallel arrays, have one array whose elements contain both the exponent and the coefficient? And instead of trying to manage all of the dynamic memory allocation yourself, why not use a STL builtin?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <vector>

struct monomial
{
    float exponent;
    float coefficient;
};

class poly
{
...
private:
    std::vector<monomial> polynomial;
....


This way your monomial exponents and coefficients are managed together, and you don't have to worry about cleaning up your arrays in your destructor because the vector template does it for you.

If you want to templatize your monomial types, you could do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <vector>

template <class T>
struct monomial
{
    T exponent;
    T coefficient;
};

template <class T>
class poly
{
...
private:
    std::vector<monomial<T>> polynomial;
....



Edit: I know that didn't answer your questions, but maybe a slightly cleaner approach will make it easier to avoid the compile problems you had.
Last edited on
hey.
thank you for your help.
i got a new try, and now im in trouble again. how to define addition in my class? is it necessary to overload the addition operator in order to add the monomials?

the code:

#include <vector>

struct monomial
{
float exponent;
float coefficient;
};

int max(int a,int b)
{
if (a>b) return a;
else return b;
}

class poly
{
public:
//constructor
poly(int);
//destructor
~poly();
//addition
void add(poly v,poly w) // this function is to add two polynomials v and w.
{
int m=max(v.polynomial.size ,w.polynomial.size);// how can i find the size of the two polynomials i want to add?
for(int i=0; i<m; i++)
polynomial[i]=v.polynomial[i]+w.polynomial[i]; //the + operator should be overloaded in order to be able to add monomials, right? is that necessary? how can i do that?


}

private:
std::vector<monomial> polynomial;

};


poly::poly(int x=0)
{
polynomial.resize(x);//changes the size of polynomial to x, right?
}

poly::~poly()
{
polynomial.clear() ;//deletes the polynomial
std::cout <<"the polynomial is deleted now."<<endl;
}


i have to sleep now.=)

greetings
rasputinxiaoshitou
You need to figure out which monomial exponents are in both polynomials and add their coefficients. Then you need to figure out which monomial exponents are in only 1 polynomial, and essentially copy that monomial to the sum.

Your function declaration has some problems, though. Because you declared it as a member function, it already has a poly associated with it. When you have 2 other poly arguments, that makes 3 polys that you have to deal with. Also, you have no return value, so you can't return the sum. In the following code:
1
2
3
4
5
6
poly a(1);
poly b(2);
poly c(3);
/* initialization here */

a.add(b, c);


it is possible that you want a to contain the sum of b and c, but I suspect what you want to do is
a = b.add(c);

In that case, you want to declare the add function as
poly add(const poly& v) const;

A couple other things to think about. Will the exponent always be an integer? If so, change the type to int. Same thing with coefficient (but there is more chance that the coefficient will have non-int values).

Note: I hesitate to bring this up because I don't want to confuse things any further, but now that I know more of what you are trying to do, I'm not sure I would use a vector of monomials. I would probably use a std::map, where each entry represents a monomial (the key is the exponent and the value is the coefficient). The map would make finding common exponents a little bit easier, and it will automatically sort the monomial terms in order of their exponent values.
hey doug4.
Thank you for your patience with me!

I tried it with maps now, but since that is the first time, that im using maps, there might be some unintelligible errors, sry. -.-

one problem is, that i have no idea how to go through all the entrys in my map. for example if i want to add one polynomial to another, how do i know were is the begining, where is the endening of the map? which of the entrys are nonempty?

I tried to handle this by cloning some of the code in that example:
http://www.cplusplus.com/reference/map/map/key_comp/,
but it seems to be incorrect.

I dont understand how the iterator and the member functions begin and rbegin are working, that is another problem.

the constructor should create a polynomial, according to the input of the user. it is adequate to use "cin"

my code is:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <map>
using namespace std;

int min(int,int);

class poly
{
public:
	//constructor
	poly();
	//destructor
	~poly();
	//addition
	 void add(poly ,poly); // this function is to add two polynomials v and w.
	
	 
	

private:
   std::map<unsigned int,float> polynomial; //exponents=keys are unsigned int type, coefficients=values are float typ

};

int min(int a,int b)
{
	if(a<b)return a;
	else return b;
}

void poly::add(poly v,poly w)
{
  int vhighest = v.rbegin()->first;     // key value of last element
  int whighest = w.rbegin()->first;     // is there someone who can explain to me how to use begin/rbegin correctly? 
  
  int m = min(v.begin(),w.begin());

  map<int,float>::iterator itv = v.begin();
  
  
  //in a first step copy v to polynomial.
  polynomial.clear();
  do { 
	polynomial[itv->first]=itv->second;
  } while ( key_comp((*itv++).first, vhighest) );

  //in a second step, add w to polynomial.
  map<int,float>::iterator itw = w.begin();
    do { 
	if (polynomial[itw]!=empty) //how to check, that the map polynomial is empty at the position itw?
		polynomial[itw]+=w[itw];// if polynomial is not empty at itw, then add the value of the map w at position itw onto it.  
	else
  } while ( key_comp((*itw++).first, vhighest) );

}


poly::poly()//the constructor should create a new polynomial, which is defined by the input of the user.
{	
 /*the input of a polynomial should follow the following rules:
 -input only the nonzero monomials
 -the input should follow the ordering of the exponents, begin with the monomial of least exponent.
 -fist input the exponent, and the input the coefficient.
 -for example: x^3+5x^2: input 2 5 3 1 
 -input a -1 to mark the end of an input. 
 */
 polynomial.clear();
 cout<<"please input a polonomial."<<endl;
 int key, float value;
 
	do //if the input of a polynomial is finished, the user has to input a "-1". 
	 {	 cin>>key;
		 cin>>value;
		 polynomial[key]=value;//inserts value at position key.
	 }
	 while (key!=-1);

 cout << "a new polynomial ist created"<<endl;
}

poly::~poly()
{
	polynomial.clear() ;//deletes the polynomial
	cout <<"the polynomial is deleted now."<<endl;
}


greetings rasputinxiaoshitou
To loop through the members of the map:

1
2
3
4
for (std::map<int, float>::iterator iter = v.begin(); iter != v.end(); iter++)
{
    ... /* your code here */
}


This will iterate through the map in numerical order of the keys. You don't need to keep entries in order--the map will do that for you, and by using iterators, you will be able to access the entries in order whenever you need to.

You should use find() (http://www.cplusplus.com/reference/map/map/find/) to figure out whether a specific map contains a specific key. If you use the [] operator on the map, you will actually be adding the monomial to the map if it didn't already exist.

So, iterate through one map. Check each found key in the second map. If found, add the values together, and insert in the results map. If the key is not found, just copy the monomial from the first map into the results map.

Next, iterate through the second map. Check each found key in the first map. If found, ignore it, because it has already been processed. If not found, copy the monomial from the second map into the results map.

You ignored my comments on your add() function. It makes no sense the way you declared it, as I discussed in my previous post.
I feel really silly right now. Accumulating the sum is actually easier than what I said in my previous post. For each initial map (v and w), do the following:

1
2
3
4
for (std::map<int, float>::iterator iter = v.begin(); iter != v.end(); iter++)
{
    results[iter->first] += iter->second;
}


This will create an entry with the given value in the map, if one doesn't yet exist, or add the value to an already-existing entry in the map.
Topic archived. No new replies allowed.