我想按照人類排序的方式對字母數字字符串進行排序。即,「A2」出現在「A10」之前,「a」肯定出現在「Z」之前!如果不編寫小型解析器,有什麼辦法嗎?理想情況下,它也會在「A1B10」之前放置「A1B1」。我看到"Natural (human alpha-numeric) sort in Microsoft SQL 2005"這個問題有一個可能的答案,但它使用各種庫函數,就像"Sorting Strings for Humans with IComparer"一樣。C++字符串排序像一個人?
下面是目前未能通過測試案例:
#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'' vector'的原因? – 2010-05-06 19:32:45
首先,A1B2將如何相對於A2B1進行排序?我從來沒有這樣做過,但我可能會先把你的字符串分成幾塊。文本,數字,文本,數字等等。然後,按照與多個成員的任何其他數據結構相同的方式進行排序,並理解數字位按數字排序而不是字符串。 – 2010-05-06 19:34:10
@Dibling:沒有特別的理由。 @Zickefoose:我將排序(升序)爲:A1B2,A1B10,A2B1。我想你可能是對的,我不得不做一些原始的練習,但是如果我可以幫忙的話,我寧願避免一些容易出錯的地方。 – 2010-05-06 19:44:47