how to insert and sort a vector of objects with un

2019-09-25 06:29发布

问题:

I am working on a program to insert objects into vector of objects only if it does not exist already keeping them sorted. so for that i have included algorithm header and using find and sort functions i am trying to execute the same but it is giving me an error I am not able to understand and solve.

This is the function for insertion where it is returning a an object of class word and data is a vector of words.

    Word *WordVector::insert(const string text){
Word newWord(text);
if(data.size()==0)
{
    data.push_back(newWord);
}

else{
    if(find(data.begin(),data.end(),newWord)!=data.end()){
        newWord.increaseCount();
    }
    else data.push_back(newWord);
    std::sort(data.begin(), data.end());
}

return &newWord;

}

and it gives me this error "Invalid operands to binary expression ('Word' and 'const Word')" in algorithm file at this method at line 7

    template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_InputIterator
find(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
{
    for (; __first != __last; ++__first)
        if (*__first == __value_)
            break;
    return __first;
}

回答1:

I would use std::lower_bound for this. It returns the correct insert position in a sorted container to keep the elements sorted.

bool insert_sorted(std::vector<int>& v, int n)
{
    // find the correct sorted insert position
    auto insert_itr = std::lower_bound(std::begin(v), std::end(v), n);

    // only insert if not a duplicate
    // test for end() first to make duplicate test safe
    if(insert_itr == std::end(v) || *insert_itr != n)
    {
        v.insert(insert_itr, n);
        return true;
    }

    return false;
}

int main()
{
    std::vector<int> ints;

    for(auto i = 0; i < 10; ++i)
        insert_sorted(ints, hol::random_number(0, 10));

    for(auto i: ints)
        std::cout << i << '\n';
}

Sample Output:

0
3
4
7
9
10

To get this to work on a user defined type you will need to define certain functions that enable the class to be sorted and tested for (in)equality.

For example:

class Word
{
public:
    Word(std::string const& s): s(s) {}

    // to enable sorting
    bool operator<(Word const& w) const { return s < w.s; }

    // enable equality matching
    bool operator==(Word const& w) const { return s == w.s; }
    bool operator!=(Word const& w) const { return s != w.s; }

    // enable printing out
    friend std::ostream& operator<<(std::ostream& os, Word const& w)
    {
        return os << w.s;
    }

private:
    std::string s;
};

bool insert_sorted(std::vector<Word>& v, Word const& w)
{
    // find the correct sorted insert position
    auto insert_itr = std::lower_bound(std::begin(v), std::end(v), w);

    // only insert if not a duplicate
    // test for end() first to make duplicate test safe
    if(insert_itr == std::end(v) || *insert_itr != w)
    {
        v.insert(insert_itr, w);
        return true;
    }

    return false;
}