Vorrei ordinare stringhe alfanumeriche nel modo in cui un essere umano le ordina. Ad esempio, "A2" viene prima di "A10", e "a" viene sicuramente prima di "Z"! C'è un modo per fare senza scrivere un mini parser? Idealmente avrebbe anche messo "A1B1" prima di "A1B10". Vedo la domanda "Natural (human alpha-numeric) sort in Microsoft SQL 2005" con una possibile risposta, ma utilizza varie funzioni di libreria, come fa "Sorting Strings for Humans with IComparer".La stringa C++ si presenta come un essere umano?
seguito è un banco di prova che attualmente non riesce:
#include <set>
#include <iterator>
#include <iostream>
#include <vector>
#include <cassert>
template <typename T>
struct LexicographicSort {
inline bool operator() (const T& lhs, const T& rhs) const{
std::ostringstream s1,s2;
s1 << toLower(lhs); s2 << toLower(rhs);
bool less = s1.str() < s2.str();
//Answer: bool less = doj::alphanum_less<std::string>()(s1.str(), s2.str());
std::cout<<s1.str()<<" "<<s2.str()<<" "<<less<<"\n";
return less;
}
inline std::string toLower(const std::string& str) const {
std::string newString("");
for (std::string::const_iterator charIt = str.begin();
charIt!=str.end();++charIt) {
newString.push_back(std::tolower(*charIt));
}
return newString;
}
};
int main(void) {
const std::string reference[5] = {"ab","B","c1","c2","c10"};
std::vector<std::string> referenceStrings(&(reference[0]), &(reference[5]));
//Insert in reverse order so we know they get sorted
std::set<std::string,LexicographicSort<std::string> > strings(referenceStrings.rbegin(), referenceStrings.rend());
std::cout<<"Items:\n";
std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
std::vector<std::string> sortedStrings(strings.begin(), strings.end());
assert(sortedStrings == referenceStrings);
}
C'è un motivo per cui si utilizza un 'set' e non solo' sort'-un 'vector'? –
In primo luogo, come sarebbe A1B2 ordinare rispetto a A2B1? Non l'ho mai fatto, ma probabilmente avrei iniziato rompendo la tua stringa in blocchi. Testo, numeri, testo, numeri, ecc. Quindi, ordina nello stesso modo in cui avresti qualsiasi altra struttura di dati con più membri, con la consapevolezza che i bit numerici si ordinano come numeri non come stringhe. –
@Dibling: nessun motivo particolare. @Zickefoose: vorrei ordinare (ascendente) come: A1B2, A1B10, A2B1. Penso che tu possa avere ragione nel dire che dovrò fare un po 'di lexing primitivo, ma preferirei evitare un errore se potessi aiutarlo. –