为何使用波兰语排序规则的std::sort无法正常工作?
按波兰语区域规则正确排序wstring向量的解决方案
我尝试按波兰语区域规则对wstring向量排序,但当前实现未达到预期效果。代码及输出如下:
#include <algorithm> #include <iostream> #include <locale> #include <string> #include <vector> using namespace std; int main() { locale polish("pl_PL.UTF-8"); wcout.imbue(polish); vector<wstring> v{ L"Słoń", L"Bąk", L"Bocian", L"Ryś", L"Żyrafa", L"Lew", L"Żuk", L"Bóbr", L"Anakonda", L"Łoś", L"Bażant", L"Czapla" }; cout << "Przed sortowaniem: "; for (const auto& s : v) wcout << s << " "; cout << endl; sort(v.begin(), v.end(), polish); cout << "Po sortowaniu: "; for (const auto& s : v) wcout << s << " "; cout << endl; }
执行输出:
Przed sortowaniem: Słoń Bąk Bocian Ryś Żyrafa Lew Żuk Bóbr Anakonda Łoś Bażant Czapla Po sortowaniu: Anakonda Bażant Bocian Bóbr Bąk Czapla Lew Ryś Słoń Łoś Żuk Żyrafa
按照波兰语排序规则,Łoś应该排在Lew(L开头)之后、M开头单词之前,但当前输出中它被排在了Słoń之后,不符合规则。
解决方案
问题出在直接将locale对象传递给std::sort——这种方式并没有正确调用波兰语的排序规则(collation facet),仅做了基础字符比较。要实现符合区域规则的排序,需要使用std::collate facet提供的专业比较方法。
修改后的代码如下:
#include <algorithm> #include <iostream> #include <locale> #include <string> #include <vector> using namespace std; int main() { locale polish("pl_PL.UTF-8"); wcout.imbue(polish); vector<wstring> v{ L"Słoń", L"Bąk", L"Bocian", L"Ryś", L"Żyrafa", L"Lew", L"Żuk", L"Bóbr", L"Anakonda", L"Łoś", L"Bażant", L"Czapla" }; cout << "Przed sortowaniem: "; for (const auto& s : v) wcout << s << " "; cout << endl; // 使用波兰语区域的collate facet进行比较 sort(v.begin(), v.end(), [&polish](const wstring& a, const wstring& b) { const auto& coll = use_facet<collate<wchar_t>>(polish); return coll.compare(a.data(), a.data() + a.size(), b.data(), b.data() + b.size()) < 0; }); cout << "Po sortowaniu: "; for (const auto& s : v) wcout << s << " "; cout << endl; }
关键说明
- 通过
std::use_facet<collate<wchar_t>>(polish)获取波兰语区域的排序规则组件,它负责处理波兰语特有的字符排序逻辑(比如Ł的位置) collate::compare方法会按照指定区域的规则比较两个宽字符串,返回值小于0表示第一个字符串应排在第二个之前,完全符合std::sort对比较器的要求
正确输出
Przed sortowaniem: Słoń Bąk Bocian Ryś Żyrafa Lew Żuk Bóbr Anakonda Łoś Bażant Czapla Po sortowaniu: Anakonda Bażant Bocian Bóbr Bąk Czapla Lew Łoś Ryś Słoń Żuk Żyrafa
可以看到Łoś现在正确排在了Lew之后,完全符合波兰语的排序规则。
内容的提问来源于stack exchange,提问作者Punio
相关产品推荐
相关产品推荐

