Reputation: 27
So I have created a program which can read a .dat file of about 20 lines containing info about different atoms (name, symbol, mass etc) and added them all to a vector of class type I made called Atom.
How would I write a function to find the atom with the highest mass?
Here is my class:
class Atom
{
string element, symbol;
float number;
float mass;
public:
Atom(string e, string s, float n, float m){
element = e; symbol = s; number = n; mass = m;
}
string getElement();
string getSymbol();
float getNumber();
float getMass();
float ratio();
friend ostream& operator<<(ostream& os, Atom c);
};
and the information is added to a vector with the following statements
ifstream fin("atoms.dat");
string E, S;
float M, N;
vector <Atom> periodic;
while(!fin.eof()){
fin >> E >> S >> M >> N;
Atom Atom(E, S, M, N);
periodic.push_back(Atom);
}
I want to be able to write a function which finds which atom has the highest mass, I've tried using a max_element function but I keep getting errors. Is there a quick way of comparing the member variables of class objects stored in a vector?
I'm currently using C++ 98 as it is what my course requires.
Thanks
Upvotes: 0
Views: 328
Reputation: 10425
I don't know what you did wrong with std::max_element
, as you haven't provided what you've tried with it.
struct CompareAtomMass
{
bool operator()(const Atom& lhs, const Atom& rhs) {
return lhs.getMass() < rhs.getMass();
}
};
and then:
vector <Atom> periodic;
Atom max_atom = *max_element(periodic.begin(), periodic.end(), CompareAtomMax());
struct CompareAtomMass
is called a function object. It's a class with operator()
overloaded to return a bool
. std::max_element
requires just such a function object to spit out the max element as it needs a way to compare your Atom
s.
EDIT:
You should mark your getter functions as const
since they don't change the inner state of the class.
string getElement() const;
string getSymbol() const;
float getNumber() const;
float getMass() const;
This will allow you to call them from a const
object of type Atom
just as the above function object requires (const Atom&
).
Upvotes: 2
Reputation: 424
It is a good idea to make your member functions const
.
This will allow this code. Otherwise just remove all const
from my code.
In case your vector is empty, you will get null pointer.
struct AtomMassComparator
{
bool operator()(const Atom& lhs, const Atom& rhs)
{
return lhs.getMass() < rhs.getMass();
}
};
const Atom* getAtomWithHighestMass(const vector<Atom>& v)
{
vector<Atom>::const_iterator it = max_element(
v.begin(), v.end(), AtomMassComparator());
return v.end() == it ? 0 : &*it;
}
Upvotes: 0
Reputation: 27028
Variation of DeiDeis answer: If you only do this at one place, and don't feel a need to keep a CompareAtomMass function class, you can use a lambda:
const auto maxIt = max_element(periodic.begin(), periodic.end(),
[](const Atom& lhs, const Atom& rhs) {
return lhs.getMass() < rhs.getMass();
));
if(maxIt != periodic.end()){
// use *maxIt ;
}
in C++14 and later you can also use auto
in lambdas:
const auto maxIt = max_element(periodic.begin(), periodic.end(),
[](const auto& lhs, const auto& rhs) {
return lhs.getMass() < rhs.getMass();
));
Upvotes: 0