Reputation: 11
I'm trying to make a function that sorts a vector of strings with this criteria:
All strings= "NULL" must go to the end of the vector and decreasing from there. The rest of the strings must keep their order.
For example given:
{"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"}
the output should be:
{"Potato","Charmander","Spaghetti","NULL","NULL","NULL"}
I tried with this but it did not quite work:
bool comp(string i, string j){
if(i=="NULL"){return i>j;}
if (j=="NULL") {return i<j;}
Thanks in advance
Upvotes: 0
Views: 448
Reputation: 1631
You can write your own version of function that puts some strings to the end i.e:
namespace myAlgo {
template<typename ForwardIter, class T >
ForwardIter moveToEnd(ForwardIter first, ForwardIter last, const T& value) {
if (first == last) {
return first;
}
ForwardIter fasterFirst = first;
//Shift strings that do not match value to the left in stable manner
while (++fasterFirst != last) {
if (*fasterFirst != value) {
*++first = *fasterFirst;
}
}
ForwardIter pivot = first;
//Fill rest with value
while (first != last) {
*++first = value;
}
return pivot;
}
}
Then just:
myAlgo::moveToEnd(vec.begin(), vec.end(), "NULL");
Upvotes: 0
Reputation: 1889
You can use partition algorithm:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
vector<string> vec {
"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"
};
partition(begin(vec), end(vec), // Partition the values
[](const string& s) { return s != "NULL"; });
copy(begin(vec), end(vec), ostream_iterator<string>{cout, " "});
cout << endl;
return 0;
}
// RESULT: Potato Spaghetti Charmander NULL NULL NULL
NOTE: If you need to maintain relative ordering use stable_partition instead.
Upvotes: 1
Reputation: 132350
You could do one of two things:
The standard library has a "partition" algorithm, which will move all elements matching a certain criterion to the end of the string.
std::vector<string> vec {
"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"
};
auto is_not_null = [](const std::string& s) { return s != "NULL"; }
auto nulls_start = std::partition(vec.begin(), vec.end(), is_not_null);
auto non_nulls_end = nulls_start;
std::sort(vec.begin(), non_nulls_end);
std::vector<string> vec {
"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"
};
auto comparator =
[](const std::string& lhs, const std::string& rhs)
{
return rhs == "NULL" or lhs <= rhs;
};
std::sort(vec.begin(), vec.end(), comparator);
Note the difference between the comparison here and your comp()
function. The comparator answers question "should the first string I got come before the second string?" - and your comp()
function just doesn't give an answer that corresponds to your requirement.
Upvotes: 1