You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用波兰语排序规则的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:52:48