C++ question regarding inserting elements into vectors
I am working through the examples in Accelerated C++.
One of the problems asks the reader to copy records for students who pass exams into the beginning of a vector called students. fgrade
is a function defined elsewhere which returns failing students.
Then one has to use the resize function to remove the extra elements from students so it only contains those who pass.
I have tried this code but it does not work. Could anyone tell me if the fault lies in the code below?
#include "stdafx.h"
#include <vector>
#include "Student_info.h"
#include "grade.h"
u开发者_如何学Csing std::vector;
// second try: correct but potentially slow
vector<Student_info> extract_fails(vector<Student_info>& students)
{
vector<Student_info> fail;
#ifdef _MSC_VER
std::vector<Student_info>::size_type i = 0;
std::vector<Student_info>::size_type count = 0;
#else
vector<Student_info>::size_type i = 0;
vector<Student_info>::size_type count = 0;
#endif
while (i != students.size()) {
if (!fgrade(students[i])) {
students.insert(students.begin(), students[i++]);
count++;
}
i++;
}
students.resize(count);
return students;
}
You can use remove_if from std::algorithm, but the functor should return the people that haven't pass (f_not_grade) instead the people that has pass:
std::remove_if(students.begin(), students.end(), f_not_grade)
Or you can look the way to negate a functor here or here to use the f_grade function without modifications and the remove_if.
Most of the common operations with containers are implemented in the STL, so use the power of the language!. Taking a while to look for this kind of functions makes us to code less and better.
Edited to delete an incorrect "()".
You increment i
twice in your loop.
A cool way to do it would be to use a custom predicate for std::sort
:
bool CompareStudentsByFailure(const Student_info & left,
const Student_info & right) {
return fgrade(left) > fgrade(right);
}
And then use it like this:
std::sort(students.begin(), students.end(), CompareStudentsByFailure);
students.resize(std::distance(students.begin(),
std::find_if(students.rbegin(),
students.rend(), fpgrade).base()));
However, Jon`s answer is a bit simpler.
As Space_C0wb0y and Artium pointed out, you incremented i twice. Also, you declare the vector fail, but never use it (unless you're doing something with it later). In addition, the macro in the function seems like overkill--it basically says the same thing twice (minus the "std::") and you might as well just use ints--easier for the next person to read and understand.
精彩评论