开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜