-
Notifications
You must be signed in to change notification settings - Fork 2
/
Polynomial.cpp
208 lines (193 loc) · 5.87 KB
/
Polynomial.cpp
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
An Nguyen + Hoang Nguyen
Polynomial Class declarations
*/
#include "Polynomial.h"
/* Function to remove the leading and trailing spaces from a string
Source: Blackboard, provided by Prof. Kuhail */
string trim(const string& the_string)
{
size_t p = the_string.find_first_not_of(" ");
if (p == string::npos) return "";
size_t q = the_string.find_last_not_of(" ");
return the_string.substr(p, q - p + 1);
}
/* Function to replace string in place
Source: http://stackoverflow.com/questions/5343190/how-do-i-replace-all-instances-of-of-a-string-with-another-string by Czarek Tomczak */
void ReplaceStringInPlace(string& subject, string& search, string& replace)
{
size_t pos = 0;
while ((pos = subject.find(search, pos)) != string::npos)
{
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
//Polynomial Class Implementation
//constructor
Polynomial::Polynomial()
{}
//this constructor parses the input to get separated terms and add them to List_Terms
Polynomial::Polynomial(string& poly)
{
//temporary variables to store the term, the coefficient and the exponent
int expo = 0;
int coef = 0;
string coefSt;
string expoSt;
string currentTerm;
// replace - with +-
ReplaceStringInPlace (poly,string("-"),string("+-"));
// split input by + to get separated terms
String_Tokenizer st1(poly, "+");
// continue to parse as long as there is a term
while (st1.has_more_tokens())
{
currentTerm = trim(st1.next_token()); // get current Term
if (currentTerm.find("x^") != string::npos) // term contains "x^"
{
string first_Token, second_Token; // variables to store the coefficient and the exponent
// split currentTerm by x^
String_Tokenizer st2(currentTerm, "x^");
first_Token = trim(st2.next_token());
second_Token = trim(st2.next_token());
if (currentTerm.find(first_Token) < currentTerm.find("x^") ) // first_Token is the coefficient
{
if (first_Token == "-") //special case (user entered "-x^...")
coefSt = "-1";
else
coefSt = first_Token;
expoSt = second_Token != "" ? second_Token : throw invalid_argument( "Invalid Input" ); // only assign the exponent if second_Token is not empty
}
else if (currentTerm.find(first_Token) > currentTerm.find("x^") ) // first_Token is the exponent (the coefficient is hidden with value 1 )
{
coefSt = "1";
expoSt = first_Token;
}
else throw invalid_argument( "Invalid Input" );
}
else if (currentTerm.find("x") != string::npos) // term contains "x"
{
//split currentTerm by x
String_Tokenizer st2(currentTerm, "x");
if (!st2.has_more_tokens()) // the term is "x" only
{
coefSt = "1";
expoSt = "1";
}
else // the term has a coefficient
{
coefSt = trim(st2.next_token());
if (coefSt == "-") //special case (user entered "-x...")
coefSt = "-1";
expoSt = "1";
}
}
else if (currentTerm.find("X") != string::npos) // term contains "X" uppercase
throw invalid_argument( "Invalid Input" );
else // term contains only the coefficient
{
coefSt = currentTerm;
expoSt = "0";
}
//convert string to int
coef= stoi(coefSt);
expo=stoi(expoSt);
//create the term and add to the list only if the coefficient is not 0
if (coef != 0)
List_Terms.push_back(Term(coef,expo));
}
}
//destructor
Polynomial::~Polynomial()
{}
//operator Definitions
const Polynomial Polynomial::operator+(const Polynomial& L_Poly) const // Adds two polynomials together
{
//iterators
list<Term>::const_iterator Itr1 = this->List_Terms.begin();
list<Term>::const_iterator Itr2 = L_Poly.List_Terms.begin();
//the result
Polynomial result = Polynomial();
Term temp; //a temp term to store term when adding
//continue till one iterator points to the tail of the list
while (Itr1!= this->List_Terms.end() && Itr2!=L_Poly.List_Terms.end())
{
//add the term with a bigger exponent to the new list
if ((Term)*Itr1 > (Term)*Itr2)
{
result.List_Terms.push_back(*Itr1);
Itr1++;
}
else if ((Term)*Itr1 < (Term)*Itr2)
{
result.List_Terms.push_back(*Itr2);
Itr2++;
}
//if 2 term have the same exponent, just add them together and add the result to new list
else
{
temp = (Term)*Itr1+(Term)*Itr2;
if (temp.get_coefficient() != 0) // only add to the result if the term has non-zero coefficient
result.List_Terms.push_back(temp);
Itr1++;
Itr2++;
}
}
//Add any remaining terms to the new list
while (Itr2 != L_Poly.List_Terms.end()){
result.List_Terms.push_back(*Itr2);
++Itr2;
}
while (Itr1 != this->List_Terms.end()){
result.List_Terms.push_back(*Itr1);
++Itr1;
}
return result; //return new list
}
//output function
ostream& operator<<(ostream& output,const Polynomial& poly)
{
//if the polynomial is empty, output 0
if (poly.isEmpty())
{
output<<0;
}
else
{
for (list<Term>::const_iterator i = poly.List_Terms.begin(); i!=poly.List_Terms.end();++i)
{
if (i == poly.List_Terms.begin() )
{ // for the first term, "+" should never be displayed
if (i->get_coefficient() > 0)
{
int Coef = i->get_coefficient();
int Expo = i->get_exponent();
if (Expo == 0 ) // if the term has exponent == 0, only the coefficient is displayed
output << Coef;
else if (Expo == 1 ) // if the term has exponent == 1, the coefficient is displayed with "x"
if (Coef == 1) // if the coefficient == 1, only "x" is displayed
output << "x" ;
else
output << Coef << "x" ;
else // display the term normally
if (Coef == 1) // if the coefficient == 1, only "x^ some exponent" is displayed
output << "x^" << Expo;
else
output << Coef << "x^" << Expo;
}
else // display the term normally
output << *i ;
}
else
output << *i ;
}
}
return output;
}
//If the list is empty, return true
//otherwise, return false
bool Polynomial::isEmpty() const
{
return (List_Terms.begin()==List_Terms.end());
}