Edit: Added the lookup table and corrected the tests in getless.
Here is another solution using std::sort and a function that tests each string and returns true if one string is less than the other in QWERTY order:
#include <algorithm>
#include <string>
#include <vector>
#include <cctype>
#include <iostream>
typedef std::vector<std::string> StringVect;
std::string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
std::vector<int> lookup(26);
bool getless(const std::string& s1, const std::string& s2)
{
for (size_t i = 0; i < std::min(s1.size(), s2.size()); ++i)
if (s1[i] != s2[i])
return (lookup[toupper(s1[i])-'A'] < lookup[toupper(s2[i])-'A']);
return s1.size() < s2.size();
};
int main()
{
StringVect sv = {{ "apple" },{ "pear" },{ "peach" }};
// build the lookup table
int i = 0;
std::for_each(sequence.begin(), sequence.end(), [&](char ch) {lookup[ch-'A'] = i; ++i; });
// sort the data
std::sort(sv.begin(), sv.end(), getless);
// output results
for (auto& s : sv)
std::cout << s << "\n";
}
Live Example
A lookup table is built that maps the character's relative ASCII position to where the character is found in the sequence string. So for example, lookup[0] is the position of A (which is 10), lookup[1] is the position of B (which is 23), etc.
The getless function scans the string and tests the character associated with the i'th character of each string with the corresponding lookup position.
The for loop basically "waits for" a character difference in the two strings being compared. If the character in the string for s1 has a lookup value less than the lookup value for the character in s2, then we immediately return "true", meaning that s1 < s2. Otherwise we return false if s1 > s2.
If the characters are equal, we keep looping until we run out of characters to compare. If both strings are equal up to the point we exit the for loop, we return true or false, depending on the length of the strings (a shorter string would mean s1 < s2).