Sorting a std::vector std::pair std::string,bool by the string?
std::vector<std::pair<std::string, bool> > v;
std::sort(v.begin(), v.end());
std::pair
overloads operator<
to sort first by the first
element then by the second
element. Thus, if you just sort the vector
using the default sort ordering (operator<
), you'll get your desired ordering.
How to sort vector of pairs float, string regardless of string
std::pair
has it's comparing operators overloaded (See the reference)
By default, operator <
for std::pair
compares first elements, if they are equal, then second elements.
You should provide your own predicate and use std::stable_sort
to preserve the order of elements if first elements in pair are equal.
std::stable_sort(vec.begin(), vec.end(),
[](const auto& a, const auto& b){return a.first < b.first;});
Segfault from using std::sort on vector pair string, int
compare
is somehow messed up and doesn't meet the requirements of Compare
. Throw away the branching and simply do:
return p1.second > p2.second;
to sort in descending order. What you have is essentially a >=
, which violates:
- For all
a
,comp(a,a)==false
- If
comp(a,b)==true
thencomp(b,a)==false
and this results in undefined behavior.
How do I sort a vector of pairs based on the second element of the pair?
EDIT: using c++14, the best solution is very easy to write thanks to lambdas that can now have parameters of type auto
. This is my current favorite solution
std::sort(v.begin(), v.end(), [](auto &left, auto &right) {
return left.second < right.second;
});
ORIGINAL ANSWER:
Just use a custom comparator (it's an optional 3rd argument to std::sort
)
struct sort_pred {
bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
return left.second < right.second;
}
};
std::sort(v.begin(), v.end(), sort_pred());
If you're using a C++11 compiler, you can write the same using lambdas:
std::sort(v.begin(), v.end(), [](const std::pair<int,int> &left, const std::pair<int,int> &right) {
return left.second < right.second;
});
EDIT: in response to your edits to your question, here's some thoughts ...
if you really wanna be creative and be able to reuse this concept a lot, just make a template:
template <class T1, class T2, class Pred = std::less<T2> >
struct sort_pair_second {
bool operator()(const std::pair<T1,T2>&left, const std::pair<T1,T2>&right) {
Pred p;
return p(left.second, right.second);
}
};
then you can do this too:
std::sort(v.begin(), v.end(), sort_pair_second<int, int>());
or even
std::sort(v.begin(), v.end(), sort_pair_second<int, int, std::greater<int> >());
Though to be honest, this is all a bit overkill, just write the 3 line function and be done with it :-P
How to sort a vector pair string , pair int , int ?
If you can't use C++11 features you can still do something like this:
typedef std::pair<std::string, std::pair<int, int>> AnkitSablok;
struct my_compare {
bool operator()(const AnkitSablok &lhs, const AnkitSablok &rhs) const {
return lhs.second < rhs.second;
}
};
int main()
{
std::vector<AnkitSablok> vec;
std::sort(vec.begin(), vec.end(), my_compare());
}
std::vector std::pair int, float and void error
You have two problems:
sort does not return a copy of the sorted range. It modifies the range provided. If you want the original to be left alone, make a copy of it first and then sort it.
std::sort
's third argument is a comparator between two values, which has the meaning of "less than". That is, "does a come before b?" For keeping the line short, I replaced yourpair<...>
type withauto
in the lambda, but it'll be deduced to "whatever type of thing" is being sorted.
Note, if you want decreasing, just change <
to >
in the lambda when it compares the two elements.
Possible fix:
auto sorted = idx_correlations; // full copy
std::sort(sorted.begin(),
sorted.end(),
[](auto const & left, auto const & right) {
return left.first < right.first; });
After that, sorted
will be a sorted vector and idx_correlations will be left unchanged. Of course, if you don't mind modifying your original collection, there's no need to make this copy (and you can take begin/end of idx_correlations.
Sorting vector of string pointers
std::string::compare
returns an int
, not a bool
. According to cppreference.com the return value is
negative value if *this appears before the character sequence specified by the arguments, in lexicographical order
zero if both character sequences compare equivalent
positive value if *this appears after the character sequence specified by the arguments, in lexicographical order strong text
The returned value is cast to bool
which evaluates to true
for all non-zero values. That means that your function returns true
for every non-identical pair of strings.
The C++ standard actually defines operator<
for strings so you can change your function to
bool cmpStrPtrs(std::string *a, std::string *b) {
return *a < *b;
}
But that still leaves a big issue in your code. You absolutely do not need pointers for this. In fact, you are leaking memory right now because you neglect to delete
them. The proper tool for this job is std::vector<std::string>
. This has the added benefit that without the extra level of indirection, std::sort
can implicitly call operator<
without a helper function, leading to the following solution.
std::vector<std::string> vec;
vec.emplace_back("AAAAA");
vec.emplace_back("aaaaa");
vec.emplace_back("xxxxx");
vec.emplace_back("bfuen");
vec.emplace_back("xylophone");
std::sort(vec.begin(), vec.end());
sorting a string vector based on the string size
Make your own custom functor to compare the size of string(s) and use that to sort the strings.
struct compare {
inline bool operator()(const std::string& first,
const std::string& second) const
{
return first.size() < second.size();
}
};
std::vector<std::string> v;
compare c;
std::sort(v.begin(), v.end(), c);
In modern c++ we can use a lambda to do the same
std::vector<std::string> v;
std::sort(v.begin(), v.end(), []
(const std::string& first, const std::string& second){
return first.size() < second.size();
});
Related Topics
Why Are By-Value Parameters Excluded from Nrvo
Expand File Names That Have Environment Variables in Their Path
Fast Color Quantization in Opencv
Initial Capacity of Vector in C++
Identifier Not Found Error on Function Call
Std::To_String - More Than Instance of Overloaded Function Matches the Argument List
Gcc Equivalent of Ms's /Bigobj
Why Lifetime of Temporary Doesn't Extend Till Lifetime of Enclosing Object
Problem with Std::Map::Iterator After Calling Erase()
I Cannot Pass Lambda as Std::Function
Repeated Typedefs - Invalid in C But Valid in C++
What Is Going on with Bitwise Operators and Integer Promotion
How to Read Files in Sequence from a Directory in Opencv
How to Use Glortho() in Opengl