Я хотел бы сортировать буквенно-цифровые строки таким образом, чтобы человек сортировал их. I.e., «A2» предшествует «A10», а «a», безусловно, предшествует «Z»! Есть ли способ сделать это без написания мини-парсера? В идеале он также поставил бы «A1B1» перед «A1B10». Я вижу вопрос "Natural (human alpha-numeric) sort in Microsoft SQL 2005" с возможным ответом, но он использует различные библиотечные функции, как и "Sorting Strings for Humans with IComparer".C++ string вроде человека?
Ниже приведен тест, который в настоящее время не удается:
#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);
}
Есть ли причина, по которой вы используете 'set', а не только' sort'-ing 'vector'? –
Во-первых, как будет выглядеть A1B2 относительно A2B1? Я никогда не делал этого, но я, вероятно, начинал бы, разбивая вашу строку на куски. Текст, Числа, Текст, Числа и т. Д. Затем сортируйте так же, как и любую другую структуру данных с несколькими членами, при том понимании, что числовые биты сортируются как числа не как строки. –
@ Отвод: нет особых причин. @Zickefoose: Я бы выбрал (по возрастанию) как: A1B2, A1B10, A2B1. Я думаю, вы вполне можете быть правы, что мне нужно будет сделать примитивный лексинг, но я бы предпочел избежать какой-либо ошибки, если я могу помочь. –