My question is related to this.
I wanted to perform a sort()
operation over the set
with the help of a lambda expression as a predicate.
My code is
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
int main() {
using namespace std;
string s = "abc";
set<string> results;
do {
for (int n = 1; n <= s.size(); ++n) {
results.insert(s.substr(0, n));
}
} while (next_permutation(s.begin(), s.end()));
sort (results.begin(),results.end());[](string a, string b)->bool{
size_t alength = a.length();
size_t blength = b.length();
return (alength < blength);
});
for (set<string>::const_iterator x = results.begin(); x != results.end(); ++x) {
cout << *x << '\n';
}
return 0;
}
But the numbers and types of errors were so complex that I couldn't understand how to fix them. Can someone tell me whats wrong with this code.
sort requires random access iterators which
set
doesn't provide (It is a bidirectional iterator). If you change the code to usevector
it compiles fine.Since I wrote the original code you're using, perhaps I can expand on it... :)
This compares by length first, then by value. Modify the set definition:
And you're good to go:
std::set is most useful to maintain a sorted and mutating list. It faster and smaller to use a vector when the set itself wont change much once it's been built.
I used the classic, sort/unique/erase combo to make the results set unique.I also cleaned up your code to be a little bit more c++0x-y.
You cannot sort a set. It's always ordered on keys (which are elements themselves).
To be more specific,
std::sort
requires random access iterators. The iterators provided bystd::set
are not random.std::sort
rearranges the elements of the sequence you give it. The arrangement of the sequence in theset
is fixed, so the only iterator you can have is aconst
iterator.You'll need to copy
results
into avector
ordeque
(or such) first.You can customize the ordering of the elements in the
set
by providing a custom predicate to determine ordering of added elements relative to extant members.set
is defined aswhere Traits is
There is background on how to use lambda expression as a template parameter here.
In your case this translates to:
Note that this will result in
set
elements with the same string length being treated as duplicates which is not what you want, as far as I can understand the desired outcome.