I'm trying to complete a program that evaluates polynomials when given an x-value.
The polynomials are stored using the STL's forward_list in objects of the class.
class PolyTerm {
private:
int _order = 0;
double _coeff = 0.0;
public:
PolyTerm() = default;
PolyTerm(int order, double coefficient) : _order(order), _coeff(coefficient) {}
void setOrder(int order) { _order = order; }
void setCoeff(double coeff) { _coeff = coeff; }
int getOrder() const { return _order; }
double getCoeff() const { return _coeff; }
};
My function which takes the object and the x-value is written as follows:
double evaluate(const forward_list<PolyTerm>& terms, double x) {
double answer = 0;
forward_list<PolyTerm>::iterator it;
while (it != terms.end()) {
answer += it->getCoeff() * pow(x, it->getOrder());
it++;
}
return answer;
}
My compiler doesn't show any errors but once I try to run the program, I get a pop-up saying "Debug Assertion Failed!" with Expression: forward_list iterators incompatible
Image of pop-up
I'm pretty sure I declared the iterator to be of the same type as the list holding the polynomial so I'm not sure why I'm getting this error.
Can anyone explain to me what's wrong?
Thanks in advance for any help.
forward_list<PolyTerm>::iterator it; it's not initialized. It must be initialized with the first element of the forward list.
forward_list<PolyTerm>::iterator it = terms.begin();
You may simplify you loop, and you will not use it
for (const auto& term : terms)
answer += term.getCoeff() * pow(x, term.getOrder());
You also could have used std::accumulate, as that will enforce the initialization using the third argument to the function. Also, since there is no need to declare and initialize iterators, there is no chance you will forget to initialize the iterator.
Here is an example. Note that there are no hand-written loops:
#include <numeric>
//...
double evaluate(const forward_list<PolyTerm>& terms, double x)
{
return std::accumulate(terms.begin(), terms.end(), 0.0, // <-- Note the initial value is 0.0 -- you can't miss it
[&](double total, const PolyTerm& p)
{ return total + p.getCoeff() * pow(x, p.getOrder()); });
}
You never initialize it.
You should have used a for loop.
You should have used a C++11 for(auto it: terms) as I think it would go.
Related
I have a class Point which has a member method to get position:
class Point {
private:
int x; int y;
public:
Point(int a, int b) {
x = a; y = b;
}
int getX() { return x; }
int getY() { return y; }
};
These are stored in a list<Point> named listPoints. I have a function which checks whether a position matches any of the points in the list:
bool checkMatch(int x, int y) {
for (Point p : listPoints) {
if (p.getX() == x && p.getY() == y) {
return true;
}
}
return false;
}
Note the . is used to access member methods of Point, but there's another way:
bool checkMatch(int x, int y) {
list<Point>::iterator p = listPoints.begin();
for (; p != listPoints.end(); ++p) {
if (p->getX() == x && p->getY() == y) {
return true;
}
}
return false;
}
What is this function doing differently to the one before, specifically why does . no longer work and I need to use -> instead to access member methods of Point? Are these foreach loops fundamentally different?
They're not different no, with some very minor exceptions. In the second loop, you're using an iterator, which is more-or-less a pointer to the object itself. It can be dereferenced to get the actual object.
You'd use iterators if you wanted to remove some elements. So say instead of checking for matches, you were removing anything that matched, you'd want to iterate with iterators.
Since you are just iterating over the entire range, it's far clearer to use your for-ranged loop. It's easier to write and clearer.
specifically why does . no longer work and I need to use -> instead to access member methods of Point?
Because the iterator is an object, which basically points to the actual object. You cannot override the dot operator, so instead operator-> is overridden to retrieve the object. One could also dereference the iterator like *p, which allows you to use the dot operator (*p).getX()
Are these foreach loops fundamentally different?
They are not fundmentally different. They are subtly different.
It's analogous to:
int a;
int* ptr = &a;
a = 10;
*ptr = 10;
The last two lines are not fundmentally different. An iterator is kinda like a pointer. Its operator* is overloaded such that using *p acts as though you are dereferencing a pointer -- you get a reference to an item in the container.
The second block of code can be changed a bit to resemble the first one.
list<Point>::iterator iter = listPoints.begin();
for (; iter != listPoints.end(); ++iter) {
Point& p = *iter;
if (p.getX() == x && p.getY() == y) {
return true;
}
}
Under the covers, the first block is exactly that.
See the documentation on the range-for loop in the standard for the details.
When trying to use a conditional copy_if algorithm to copy only the values that are lower than mean of values in a vector into another vector, I hit a snag with my function object:
struct Lower_than_mean
{
private:
double mean;
vector<double>d1;
public:
Lower_than_mean(vector<double>a)
:d1{a}
{
double sum = accumulate(d1.begin(), d1.end(), 0.0);
mean = sum / (d1.size());
}
bool operator()(double& x)
{
return x < mean;
}
};
int main()
{
vector<double>vd{ 3.4,5.6, 7, 3,4,5.6,9,2 };
vector<double>vd2(vd.size());
copy_if(vd.begin(), vd.end(), vd2, Lower_than_mean(vd));
}
What is the right way of going about this?
You used vd instead of vd.begin() in the call to std::copy_if.
But, seriously, you didn't bother to even read your compiler output...
Also, like #zch suggests - your approach doesn't make sense: Don't keep re-calculating the mean again and again. Instead, calculate it once, and then your function becomes as simple [mean](double x) { return x < mean; } lambda.
I have the following C++ code:
Some_class * temp1 = findTemp1(...); // returns NULL or a valid pointer
Some_class * temp2 = findTemp2(...); // returns NULL or a valid pointer
Some_class * temp3 = findTemp3(...); // returns NULL or a valid pointer
Now I would like to count how many of these returned a valid pointer (0, 1, 2 or 3).
The only way I can think of is just to test them one by one:
int count = 0;
if (temp1)
count++;
if (temp2)
count++;
if (temp3)
count++;
For 3 pointers, it's not too bad, but it doesn't scale well. Is there a more efficient way assuming I don't redefine the findTempN funcitons (to maybe pass in the counter)?
Thanks a lot for your quick replies! No, I am not going to change the code, I was just wondering what were my other options. I also realized that I cannot be asking for something "scalable" if I am using distinct literals like that to define the 3 pointers. Of course, I didn't think of the things you replied :)
Well, since this is C++ we can go crazy in the quest for terseness... for example:
int count = !!temp1 + !!temp2 + !!temp3;
Update: I probably owe Ivan an explanation of what's going on here.
Assuming temp is any kind of pointer, !temp forces the coercion of the pointer's value to bool (we want to do this) and negates the result (this is a side effect that we do not want). This results in true if the pointer is null and false if the pointer is not null, which is the opposite of what we 'd like. So we add another ! in front to negate the result again.
This leaves us with adding three bool values which coerces them to int and performs the addition, whereupon we have our final result.
You might find it easier to understand the completely equivalent
int count = (bool)temp1 + (bool)temp2 + (bool)temp3;
which I did not use because typing !! is three characters shorter than (bool) (note: you might think that this is a nice trick, but when writing code it is a really bad idea to make decisions based on how many characters you have to type).
The moral of the story is that doing this type of thing can be called either clever or atrocious, depending on who you ask -- but in C++ there has traditionally been high tolerance for atrocities.
Note that if the pointers were in some type of collection to begin with, you could write much better-looking code using std::count_if, e.g.:
bool isNotNull(void* ptr) {
return ptr != 0;
}
std::vector<Some_class*> vec;
vec.push_back(temp1);
vec.push_back(temp2);
vec.push_back(temp3);
int count = std::count_if(vec.begin(), vec.end(), isNotNull);
See it in action.
Or, as very cleverly suggested by MSalters in the comments, you can lose the isNotNull function by counting the pointers which are 0 and subtracting this from the number of all pointers -- but for this, you will need to somehow know what this number is (easy if they are in a vector):
int count = vec.size() - std::count(vec.begin(), vec.end(), 0);
See it in action.
#define N 3
typedef Some_class *PointerGenerator(...);
PointerGenerator funcs[N];
func[0] = &findTemp1;
func[1] = &findTemp2;
func[2] = &findTemp3;
Some_class *ptrs[N];
for(size_t i = 0; i < N; ++i) ptrs[i] = func[i]();
for(size_t i = 0; i < N; ++i) { if(ptrs[i]) ++count; }
C++0x variant:
int count = std::count_if(ptrs, ptrs + N, [](const Some_class *i) -> bool { return i != NULL; } );
The code you have is Good Enough, don't mess with it.
Introducing subtlety is a common novice error, don't do it.
That said, NULL is a valid pointer value, and you can do e.g. count += !!temp1 + !!temp2 + !!temp3 (but that would be newbie obfuscation, do not actually do that).
Cheers & hth.,
If all of the pointers are the same type, put the pointers in a table,
or if you can't do that, make a table of pointers to the pointers. Then
use std::count or std::count_if. Something like:
SomeClass** pointerTable[] =
{
&temp1,
&temp2,
&temp3,
// ...
};
struct IndirectIsNoNull
{
bool operator()( SomeClass** p ) const
{
return *p != NULL;
}
};
// ...
int validPointerCount = std::count_if( begin( pointerTable ),
end( pointerTable ),
IndirectIsNoNull() );
Introduce a static counter.
template<typename T>
struct ValidPointer
{
static unsigned int count;
};
template<typename T>
unsigned int ValidPointer<T>::count = 0;
template<typename T>
static void isValid (const T* const p)
{
if(p)
ValidPointer<T*>::count++;
}
Usage:
isValid(temp1);
isValid(temp2);
...
At any point of time, if you want to retrieve then,
unsigned int count = ValidPointer<Some_class*>::count;
This code can be improved as per your requirement.
Do you need the pointers afterwards? temp suggests otherwise. In that case, you can eliminate those:
int count = 0;
if (findTemp1())
count++;
if (findTemp2())
count++;
if (findTemp3())
count++;
Hide the counter in a class:
class Some_class {};
typedef Some_class* (*FindFunction_t)();
Some_class* findTemp1() {return NULL;}
Some_class* findTemp2() {return new Some_class;}
Some_class* findTemp3() {return new Some_class;}
class Finder
{
public:
Finder() : count_(0) {}
Some_class* CallAndCount(FindFunction_t fn) {return Count(fn());}
int GetCount() const {return count_;}
private:
Some_class* Count(Some_class* p) {if(p) count_++; return p;}
int count_;
};
int main()
{
Finder f;
Some_class* temp1 = f.CallAndCount(findTemp1);
Some_class* temp2 = f.CallAndCount(findTemp2);
Some_class* temp3 = f.CallAndCount(findTemp3);
std::wcout << f.GetCount() << L"\n";
}
The names aren't the best and there are memory leaks but you should get the idea.
I think this meets your objective of scalability although you would need to add template functions if your find functions were to take parameters
I'm working on a problem which requires me to use the STL linked list class to represent a polynomials. I've made a good start on getting the class definition, however I'm a little confused as to where to go next (novice programmer - please excuse my potential ignorance).
class Polynomial
{
public:
Polynomial(); //Default constructor
Polynomial(pair<double,int>); //Specified constructor
void add(Polynomial);
Polynomial multiply(Polynomial);
void print();
private:
list<int> order_terms;
list<double> coeffs;
};
I have two questions:
1) It seems more elegant to store the terms and coefficients as a pair - however I'm unsure how to get that working using the STL list.
2) Regarding the add member function, I'm unsure how to implement it such that I can define a Polynomial and then add terms to it like this:
Polynomial test(pair<3.14,0>);
Polynomial test_2(pair<2,1>);
test.add(test_2);
The main thing I'm having issues with understanding how to access the terms stored in the other object and linking it to the first Polynomial.
Any help greatly appreciated.
EDIT: Code for the add() function - currently not working
void Polynomial::add(const Polynomial& rhs)
{
//Perform some sort of sort here to make sure both lists are correctly sorted
//Traverse the list of terms to see if there's an existing nth order
//term in the list on the left-hand-side polynomial.
list<int>::iterator itr;
list<int>::iterator itl;
for(itr=rhs->terms.begin(); itr!=rhs->terms.end(); itr++)
{
bool match=0;
//See if there's an existing terms, if so add to it
for(itl=terms.begin(); itl!=terms.end(); itl++)
{
if(*itl->second)==*itr->second)
{
*itl->first+=*itr->first;
match = 1;
}
}
//If not, this is the first nth order term so just push it onto the list
if(!match){ terms.push_back(*itr); //Perform the sort again }
}
To use a pair in a list you can do:
list<pair<double, int> > - note the space between the >. It's also nice to do something like
typedef pair<double, int> TermCoeff;
list<TermCoeff> equation;
To sort a list:
list<TermCoeff> equation;
// insert items
equation.sort(coeff_compare);
There are pre-defined comparator functions for a pair in the <utility> header. They compare the first elements and then the second ones if first is equal.
For your second question you should remember that an object of a class can access the member variables of an object of the same class, even if they are private. If you don't leave any gaps in your coefficients (in the constructor fill in missing ones with the second value of the pair set to 0) this means your add method can look like:
Polynomial& Polynomial::add(const Polynomial& rhs) {
// constructor should sort all terms and enforce that all terms are present
// lhs = current object (left hand side of operator)
// rhs = other object (right hand side of operator)
// example: lhs.add(rhs)
list<TermCoeff>::const_iterator rhs_iter = rhs.terms.begin();
list<TermCoeff>::iterator lhs_iter = terms.begin();
while(rhs_iter != rhs.terms.end()) {
if (lhs_iter != terms.end()) {
// add because we aren't at the end of current object's terms
lhs_iter->second += rhs_iter->second;
++lhs_iter;
} else {
// insert because we are at the end of current object's terms
terms.push_back(*rhs_iter);
lhs_iter = terms.end(); // keep the iterator at the end
}
++rhs_iter;
}
return *this;
}
int main (int argc, const char * argv[])
{
list<TermCoeff> first, second;
first.push_back(TermCoeff(0, 0.0)); // empty
first.push_back(TermCoeff(1, 5.0));
first.push_back(TermCoeff(2, 5.0));
second.push_back(TermCoeff(0, 6.0));
second.push_back(TermCoeff(1, 0.0)); // empty
second.push_back(TermCoeff(2, 8.0));
second.push_back(TermCoeff(3, 9.0));
Polynomial first_eq(first);
Polynomial second_eq(second);
first_eq.add(second_eq);
first_eq.print();
return 0;
}
Note that I returned a reference to the current object. This is a nice thing to do in an addition method because then you can chain additions:
first.add(second).add(third);
or
first.add(second.add(third));
Others have explained list<pair<double, int> > (and I like shelleybutterfly's suggestion to derive Polynomial from the list, except that I'd make it protected, not public, so that outside code is not too free to mess with the contents of the list).
But the add function is a little tricky, because adding two polynomials doesn't generally mean concatenating them or adding their terms together. The operation is actually more like merging-- and you'll soon see that the lists must be sorted. (In fact, it's more natural to represent polynomials as vectors, but I guess that's not the assignment.)
I suggest you implement Polynomial::add(pair<double, int>), first, then implement the other one (add(Polynomial &)) in terms of that.
I don't want to spell it out too much, since this looks like homework. Is this enough to point you in the right direction?
EDIT:
Your new code looks correct (albeit inefficient) if you fix a couple of bugs:
void Polynomial::add(const Polynomial& rhs)
{
// Don't forget to implement the sorting routine.
// The iterators must be of the correct type. And itr must be const,
// since you have declared rhs to be a const reference. The compiler
// will not allow you to have an iterator with the power to alter
// a const thing.
list<pair<double,int> >::const_iterator itr;
list<pair<double,int> >::iterator itl;
for(itr=rhs->terms.begin(); itr!=rhs->terms.end(); itr++)
{
bool match=false;
for(itl=terms.begin(); itl!=terms.end(); itl++)
{
// You have an extra parenthesis here, and too much dereferencing.
if(itl->second == itr->second)
{
itl->first+=itr->first;
match = true;
}
}
if(!match)
{ terms.push_back(*itr); //Perform the sort again
} // Be careful not to catch the closing brace in a comment
}
}
Once it is working, you can think about ways to make it cleaner and more efficient. For example, if you insert the new term in the right place, the list will always be in the right order and there will be no need for a sort routine.
As for using a pair, why not use a list<pair<double, int>> (list< pair<double, int> > for older compilers)? Or you could even define a separate class to hold your pair like so:
// example is implemented inline, you could always pull it out to
// your source file; although it's even possible that you could
// do everything inline if you want to allow just including a
// header but not having to link a separate file.
class CoeffAndTerm : public pair<double,int>
{
public:
// if you need it you should put extra functions here to
// provide abstractions:
double getTotalValue()
{
return first * second;
}
}
and then use
list<CoeffAndTerm> Polynomial;
as your variable, or even
// same stuff goes for this class RE: the inline function definitions
class Polynomial : public list<CoeffAndTerm>
{
public:
// same goes here for the abstraction stuff maybe things
// like in your current Polynomial class; assuming some
// functions here ...
Polynomial Multiply(Polynomial other)
{
Polynomial Result = new Polynomial();
for (int i=0; i < size(); ++i)
{
Result.addCoeffAndTerm(
new CoeffAndTerm(
other.first * first,
other.second * second
);
}
return Result;
}
}
so that you've got Polynomial being a derivation of the list itself. Not sure the exact usage of the Polynomial, so it's hard for me to speak to which makes more sense, but I like this way better as a general rule for a type such as this; seems to be that the polynomial "is a" list of coefficient and terms, it doesn't just "have" one. :) I'm sure that's debatable, and again it depends on the actual usage of your code.
for the operations, you could do reference returns, as in one of the other examples, but I have implemented the multiply without modifying the existing value, which you could also do for Add, Subtract, etc. so, assuming First, Second, Third, etc. are other polynomials
Polynomial Result = First.Multiply(Second).Add(Third).Subtract(Fourth);
you could also implement copy constructor, operator =, operator +, operator *, operator / and then do things that look like normal math:
Polynomial Result = First * Second + Third - Fourth;
While it's possible to use std::pair to group the term order and coefficient, I would recomment against it: it's not very readable - it's not clear what 'first' and 'second' means, and C++ will implicitly cast between numeric types - and you get no benefit from the added functionality of pair (ordering).
Instead, create a class like:
class Term {
double coeff_;
int exp_;
public:
Term(double coeff, int exp): coeff_(coeff), exp_(exp) {}
double coefficient() const { return coeff; }
int exponent() const { return exp; }
[...]
};
class Polynomial {
std::list<Term> terms;
[...]
Making fields public (e.g. by using struct or publicly deriving from pair) for performance reasons is not a good idea: inline constructor, getters and setters are just as fast as reading or writing the variable directly, and they have the advantage of encapsulating the implementation.
For that matter, you may want to create separate types to wrap polynomial coefficients and exponents themselves, in order to avoid mixing up numeric types, and performing nonsensical operations e.g.:
class Coefficient {
double val;
public:
explicit Coefficient(double value): val(value) {}
double getValue() { return val; }
double operator*(double rhs) { return val*rhs; }
Coefficient operator+(const Coefficient& rhs) {
return Coefficient(val+rhs.val);
}
[...]
};
etc.
Another possibility: instead of using a class, you could make as struct to represent the term and coefficient; you still can define methods on it just like a class, but the members are public by default which may make sense for efficiency reasons, especially if you're doing a lot of processing with these things. So, maybe:
struct CoeffAndTerm
{
int Term;
double Coeff;
private CoeffAndTerm(int parTerm, double parCoeff)
{
Term = parTerm;
Coeff = parCoeff;
}
public static CoeffAndTerm Make(int parTerm, double parCoeff)
{
return new CoeffAndTerm(parTerm, parCoeff);
}
// etc. and otherwise you can just do things as given in the example
// with the classes deriving from list<pair<int, double>>, e.g.,
// silly example again
public double getTotalValue()
{
return first * second;
}
}
and same applies otherwise as in the first example, again giving more direct access than that example had, but still allowing for the abstraction methods to be placed directly on the object
struct Polynomial : public list<CoeffAndTerm>
{
list<CoeffAndTerm> CoefficientsAndTerms;
Polynomial Multiply(Polynomial other)
{
Polynomial Result = new Polynomial();
for (int i=0; i < size(); ++i)
{
Result.addCoeffAndTerm(
new CoeffAndTerm(
other.first * first,
other.second * second
);
}
return Result;
}
// etc.
}
I'm trying to walk through a list. Here are some declarations:
list<CG1_Edge*> ActiveEdges;
list<CG1_Edge*>::iterator ActiveEdgeIterator;
Sometimes, this code segfaults on line 2:
for (this->ActiveEdgeIterator = this->ActiveEdges.begin(); this->ActiveEdgeIterator != this->ActiveEdges.end(); ++this->ActiveEdgeIterator) {
CG1_Edge* currentEdge = *this->ActiveEdgeIterator;
if (currentEdge->y_up < y)
this->ActiveEdges.erase(this->ActiveEdgeIterator);
}
Are there any common reasons why this might result in a segfault?
You should use something like:
for (this->ActiveEdgeIterator = this->ActiveEdges.begin(); this->ActiveEdgeIterator != this->ActiveEdges.end(); ) {
CG1_Edge* currentEdge = *this->ActiveEdgeIterator;
if (currentEdge->y_up < y)
this->ActiveEdgeIterator = this->ActiveEdges.erase(this->ActiveEdgeIterator);
else
++this->ActiveEdgeIterator;
}
since erase returns an iterator positionned at the next element.
(Note: having that iterator as a member looks strange.)
Begemoth's comment should be the accepted answer. According to the standard erase invalidates "all iterator and references to elements after position"(my mistake; this was for vector and possibly other containers; so at least to avoid surprises you should do well to use the algorithm version instead).
So you'd be safer already using rbegin() and rend(). But why not use the std::alogirthms!
struct Predicate
{
int _y;
explicit Predicate(int y) : _y(y) {}
bool operator()(const CG1_Edge edge) const
{
return currentEdge->y_up < _y;
}
};
std::erase(
std::remove_if(this->ActiveEdges.begin(), this->ActiveEdges.end(), Predicate(y)),
this->ActiveEdges.end());