Polynomial Class...

Pages: 12
You've got the meaning of simplify right.

I don't have time to look at your code more closely. But I would consider using the copy constructor approach to implement add.

And I'm not going to have time to look at you code more closely until the weekend. But will see what you're up to then.

Andy
Last edited on
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
Polynomial Polynomial::operator+ (Polynomial& object)
{
	Term *factor1 = this->top;
	Term *factor2 = object.top;
	Polynomial result;
	bool valAdded = false;

	if(factor2->getN() > factor1->getN())
	{
		Term *temp = factor1;
		factor1 = factor2;
		factor2 = temp;
	}

	Term *lowEx = factor2;

	//This will add all elements from factor1 & factor2 to result,then simplify.

	while(factor1 != NULL)
	{
		result.addNew(factor1->getA(),factor1->getN());
		factor1 = factor1->getLink();
	}//End 1

	while(factor2 != NULL)
	{
		result.addNew(factor2->getA(),factor2->getN());
		factor2 = factor2->getLink();
	}//End 2

	//cout << result;
	result.simplify();
	
	return result;
}



Addition work perfect now.
Last edited on
Cool!!
Can't wait for weekend to have you check some of bugs I found but hard to fix. (I'm suck at debugging)

But the code I wrote successfully will be put here too to show my effort after following your constructive opinions and have you to check them if you could find any bug.Plz at least have some comments when you can come back and check the code.

Here are evaluate function for term and polynomial :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double Term::evaluate(double theX)
{
	return (a * pow(theX,static_cast<double>(n)));
}

double Polynomial::evaluate(double theX)
{
	double result = 0;
	Term *temp = top;
	while(temp != NULL)
	{
		result = result + temp->evaluate(theX);
		temp = temp->getLink();
	}
	return result;
}


Also the - operator,just the opposite of + :

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
Polynomial Polynomial::operator- (const Polynomial& object)
{
	Term *factor1 = this->top;
	Term *factor2 = object.top;
	Polynomial result;
	bool valAdded = false;

	//This will add all elements from factor1 & factor2(negatively) to result,then simplify.

	while(factor1 != NULL)
	{
		result.addNew(factor1->getA(),factor1->getN());
		factor1 = factor1->getLink();
	}//End 1

	while(factor2 != NULL)
	{
		result.addNew(-factor2->getA(),factor2->getN());
		factor2 = factor2->getLink();
	}//End 2

	result.simplify();
	
	return result;
}


And the almighty * operator (LOL I KEED)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Polynomial Polynomial::operator* (const Polynomial& object)
{
	Term* factor1 = this->top;
	Term* factor2 = object.top;
	Polynomial result;
	while(factor1 != NULL)
	{
		while(factor2 != NULL)
		{
			result.addNew(factor1->getA() * factor2->getA(),factor1->getN()+factor2->getN());
			factor2 = factor2->getLink();
		}
		factor2 = object.top;
		factor1 = factor1->getLink();
	}
	result.simplify();
	return result;
}



Now I got some error : If you could look at them,I would really appreciate.If not,have a good weekend anyway !.

1. >> operator ?

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
85
86
87
88
89
90
91
92
93
94
istream& operator >> (istream& in,Polynomial& object)
{
	cout << "Enter A Polynomial : " << endl;
	char next;
	int sign = 0;
	int theA,theN;
	cin.get(next);
	bool savedSign = false;

	while(next != '\n')
	{
		if(next != ' ')
		{
			if(next == '-')
			{
				if(sign == 0)
					sign = -1;
				else
					sign = -sign;
				cin.get(next);
				if(next != ' ')
				{
					cin.putback(next);
					cin.putback('-');
					savedSign = false;
				}
				else
				{
					cin.get(next);
					if(next != '+' && next != '-')
						cin.putback(next);
					else if(next == '-')
					{
						sign = -sign;
						savedSign = true;
						cin.putback(next);
					}
					else
						cin.putback(next);
				}
				cin.get(next);
			}
			else if(next == '+')
			{
				if(sign == 0)
					sign = 1;
				cin.get(next);
				if(next != ' ')
				{
					cin.putback(next);
					cin.putback('+');
				}
				cin.get(next);
			}
			if((next >= '0') && (next <= '9'))
			{
				
				cin.putback(next);
				cin >> theA;
				cin.get(next);//Take the word x
				if(next != 'x' && (next == ' ' || next == '\n'))
				{
					theN = 0;
					cin.putback(next);
				}
				else if(next == 'x')
				{
					cin.get(next);//Take '^' or ' '
					if(next == ' ' || next == '\n')
					{
						theN = 1;
						cin.putback(next);
					}
					else if(next = '^')
					{
						cin >> theN;
					}
				}
				if(sign >= 0)
					object.addNew(theA,theN);
				if(sign < 0)
					object.addNew(-theA,theN);
				savedSign = false;
				if(!savedSign)
					sign = 0;
			}
		}
		cin.get(next);
	}

	//CAUTION : THIS FUCTION HAS A BUG IF YOU ADD A MINUS LIKE A + (-B)
	//IT WORKS WELL FOR SUBTRACT A MINUS AND A PLUS.
	return in;
}



ERROR DESCRIPTION :

1
2
	//CAUTION : THIS FUCTION HAS A BUG IF YOU ADD A MINUS LIKE A + (-B)
	//IT WORKS WELL FOR SUBTRACT A MINUS AND A PLUS. 


2. I can't also input the value 0. but I can input 1 to 9 to have a poly of X^0...Where could it go wrong ?

That's All...I think it could be better for a sort to help them in order.Sorting is different than Simpifying.

Thanks Guys.
Last edited on
The i/p code is bit too complicated to "debug" by sight. But I would prob do it using a little state machine, and without any putback() calls. You just get char after char, and handle it depending what you are currently doing (collecting digits of a number, processing spacrs, etc)

The following code is for illustrative purposes; I've not really thought through the detail of the logic.

And I would prob factor out the contents of each case in the switch statement to its own function. And even make the whole thing a little helper class.

Andy

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
	enum State
	{
		in_white_space,
		in_number,
		in_identifier,
		in_operator,
		// etc
		end
	};

	State state = in_white_space;

	string number;
	string identifer;
	string operator;
	// etc

	int number_value = 0;
	// etc

	while(state != end)
	{
		char next = cin.read();

		switch(state)
		{
			case whitepace:
			{
				if(isdigit(next))
				{
					number += next;
					state = in_number;
				}
				else if(isalpha(next)) // identifier
				{
					// handle identifer
					state = in_identifier;
				}
				else
				{
				}
			}
			break;

			case in_number:
			{
				if(isspace(next))
				{
					if(!number.empty()) // end of number
					{
						number_value = atol(number.c_str()); // assuming int for now
						number.clear();
					}
					else
					{
						// etc
					}

					state = in_white_space;
				}
				else if(is_operator(ch)) // custom function!
				{
					// etc

					state = in_operator;
				}
				else
				{
					number += next;
				}
			}
			break;

			default:
			{
				// etc
			}
		}
	}
Last edited on
CODA

Did you get your code to work ok in the end?

I copied the latest versions of each of your methods, working backwards through the messages and got the basics to run by:

# build fixes

- added double evaluate(double theX); to declaration of class Polynomial
- provided an implementation of bool Polynomial::isEmpty() const, which just tested for a null pointer
- changed the function header of operator= from
Polynomial Polynomial::operator+ (Polynomial& object)
to (i.e. added missing const)
Polynomial Polynomial::operator+ (const Polynomial& object)
- added an implementation of ostream& operator << (ostream& out,const Term& object).

1
2
3
4
5
6
7
8
9
ostream& operator << (ostream& out,const Term& object)
{
	out << object.a;
	if(1 == object.n)
		out << "x";
	else if(0 != object.n)
		out << "x^" << object.n;
	return out;
}


# to run basics tests (i.e. building instances, adding the, displaying them) without crashing

- modified the non-default constructors so they also nulled the ember variable top
1
2
	Polynomial(int theA) : top(NULL) {addNew(theA,0);}; 
	Polynomial(int theA,int theN) : top(NULL) {addNew(theA,theN);}

- modified operator<< to put +s inbetween terms (really should use -/+ as appropriate)

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
ostream& operator << (ostream& out,const Polynomial& object)
{
	Term *temp = object.top;
	if(temp == NULL)
		out << "0";
	else
	{
		bool show_plus = false; // new

		while(temp->getLink() != NULL)
		{
			if(show_plus)             // new
				out << " + ";     // new
			else                      // new
				show_plus = true; // new

			out << *temp;
			temp = temp->getLink();
		}

		if(show_plus)         // new
			out << " + "; // new
		out << *temp;
	}
	return out;
}


BUT I didn't check operator- or operator* as I had run out of steam after looking at operator>> (see next post)
Last edited on
And to get operator>> to work I had to:
- swap cin -> in
- handle eof(), so knows what to do when there are no more chars
- plus init all variables (not strictly necessary, but a good habit)

Note that while it now works for the test cases mentioned previously, it will prob have a problem with a bad string. That would be easier using the state machine approach, by setting an error state if an unexpected char is found.

Andy

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
istream& operator >> (istream& in,Polynomial& object)
{
	//removed - cout << "Enter A Polynomial : " << endl;
	char next = '\0'; // initialize, etc
	int sign = 0;
	int theA = 0;
	int theN = 0;
	bool savedSign = false;

	in.get(next); // replaced all cin with in

	while(next != '\n')
	{
		if(next != ' ')
		{
			if(next == '-')
			{
				if(sign == 0)
					sign = -1;
				else
					sign = -sign;
				in.get(next); // etc (cin -> in)
				if(next != ' ')
				{
					in.putback(next);
					in.putback('-');
					savedSign = false;
				}
				else
				{
					in.get(next);
					if(next != '+' && next != '-')
						in.putback(next);
					else if(next == '-')
					{
						sign = -sign;
						savedSign = true;
						in.putback(next);
					}
					else
						in.putback(next);
				}
				in.get(next);
			}
			else if(next == '+')
			{
				if(sign == 0)
					sign = 1;
				in.get(next);
				if(next != ' ')
				{
					in.putback(next);
					in.putback('+');
				}
				in.get(next);
			}
			if((next >= '0') && (next <= '9'))
			{
				in.putback(next);
				in >> theA;
				in.get(next);//Take the word x
				if(next != 'x' && (in.eof() || (next == ' ' || next == '\n'))) // handle end of stream
				{
					theN = 0;
					in.putback(next);
				}
				else if(next == 'x')
				{
					in.get(next);//Take '^' or ' '
					if(in.eof() || (next == ' ' || next == '\n')) // handle end of stream
					{
						theN = 1;
						in.putback(next);
					}
					else if(next = '^')
					{
						in >> theN;
					}
				}
				if(sign >= 0)
					object.addNew(theA,theN);
				if(sign < 0)
					object.addNew(-theA,theN);
				savedSign = false;
				if(!savedSign)
					sign = 0;
			}
		}

		// handle end of stream
		if(in.eof())
			next = '\n';
		else
			in.get(next);
	}

	//CAUTION : THIS FUCTION HAS A BUG IF YOU ADD A MINUS LIKE A + (-B)
	//IT WORKS WELL FOR SUBTRACT A MINUS AND A PLUS.
	return in;
}

Last edited on
Based on the original spec, the code you're posted today is missing:

- a destructor
- a copy constructor
- operator=

Until you implement these, the instances of your polynomial could end up sharing their internal lists of terms (as only the pointer address is copied, rather than the whole list). And the list you create, will result in a memory leak.

But the code so far is most working!

Quite and interesting little problem, with plenty of scope for additional features.

Andy
When I edit all the things you mentioned,the input of zero is ok,but still can't add a minus.

3x^2 + -3x + 5

It output-ed 3x^2 + 3x + 5


And because I didn't give you the full code (too long) but I already included constructors for them.as so for some of things you mentioned.

My full code : (just what it was from the beginning then) I comment the destructor out.

http://pastebin.com/Zv50L1fj


But how can I implement destructor ? I have to move to the last node and delete it first...then run from beginning again to delete the last node (which was the second last node) Like this :

A B C D E F

A B C D E * (* stands for deleted node)

A B C D * *

A B C *

A B *

A *

*

If this the only way,how the word virtual of destructor will be useful for this case ?

I'll work on the operator = now...I forgot.

EDiT : Why can't I use cin ?
Last edited on
Topic archived. No new replies allowed.
Pages: 12