Sort std::vector but ignore a certain number

前端 未结 6 617
我寻月下人不归
我寻月下人不归 2021-01-28 12:05

I have an std::vector of the size 10 and each entry is initially -1. This vector represents a leaderboard for my game (high scores), and -1 just means th

相关标签:
6条回答
  • 2021-01-28 12:08

    An alternative approach is to use reserve() instead of resize().

    std::vector<int> myVector;
    myVector.reserve(10);
    
    for each line in file:
      int number_in_line = ...;
      myVector.push_back(number_in_line);
    
    std::sort(myVector.begin(), myVector.end());
    

    This way, the vector would have only the numbers that are actually in file, no extra (spurious) values (e.g. -1). If the vector need to be later passed to other module or function for further processing, they do not need to know about the special nature of '-1' values.

    0 讨论(0)
  • 2021-01-28 12:20

    From your description, it appears that the score can be never negative. In that case, I'd recommend the scores to be a vector of unsigned int. You can define a constant

    const unsigned int INFINITY = -1;
    

    and load your vector with INFINITY initially. INFINITY is the maximum positive integer that can be stored in a 32 bit unsigned integer (which also corresponds to -1 in 2's complement)

    Then you could simply sort using

    sort(v.begin(),v.end());
    

    All INFINITY will be at the end after the sort.

    0 讨论(0)
  • You can provide lambda as parameter for sort:

    std::sort(myVector.begin(), myVector.end(),[]( int i1, int i2 ) {
        if( i1 == -1 ) return false;
        if( i2 == -1 ) return true;
        return i1 < i2; }
    );
    

    here is the demo (copied from Kerrek)

    but it is not clear how you realize where is which score after sort.

    0 讨论(0)
  • 2021-01-28 12:26

    std::sort supports using your own comparison function with the signature bool cmp(const T& a, const T& b);. So write your own function similar to this:

    bool sort_negatives(const int& a, const int& b)
    {
        if (a == -1) {
            return false;
        }
        if (b == -1) {
            return true;
        }
        return a < b;
    }
    

    And then call sort like std::sort(myVector.begin(), myVector.end(), sort_negatives);.

    EDIT: Fixed the logic courtesy of Slava. If you are using a compiler with C++11 support, use the lambda or partition answers, but this should work on compilers pre C++11.

    0 讨论(0)
  • 2021-01-28 12:28

    Combine partitioning and sorting:

    std::sort(v.begin(),
              std::partition(v.begin(), v.end(), [](int n){ return n != -1; }));
    

    If you store the iterator returned from partition, you already have a complete description of the range of non-trivial values, so you don't need to look for −1s later.

    0 讨论(0)
  • 2021-01-28 12:32

    For the following, I assume that the -1 values are all placed at the end of the vector. If they are not, use KerrekSB's method, or make sure that you do not skip the indices in the vector for which no valid score is in the file (by using an extra index / iterator for writing to the vector).

    std::sort uses a pair of iterators. Simply provide the sub-range which contains non--1 values. You already know the end of this range after reading from a file. If you already use iterators to fill the vector, like in

    auto it = myVector.begin();
    while (...) {
        *it = stoi(...);
        ++it;
    }
    

    then simply use it instead of myVector.end():

    std::sort(myVector.begin(), it);
    

    Otherwise (i.e., when using indices to fill up the vector, let's say i is the number of values), use

    std::sort(myVector.begin(), myVector.begin() + i);
    
    0 讨论(0)
提交回复
热议问题