【发布时间】:2015-07-21 01:35:44
【问题描述】:
虽然通过在 std::sort 中指定 UTF-8 语言环境,我可以成功地对带有重音元音的西班牙语单词进行排序,
// [[Rcpp::export]]
std::vector<std::string> sort_words(std::vector<std::string> x) {
std::sort(x.begin(), x.end(), std::locale("en_US.UTF-8"));
return x;
}
/*** R
words <- c("casa", "árbol", "zona", "árbol", "casa", "libro")
sort_words(words)
*/
returns (as expected):
[1] "árbol" "árbol" "casa" "casa" "libro" "zona"
我不知道如何对地图做同样的事情:
// slightly modified version of tableC on http://adv-r.had.co.nz/Rcpp.html
// [[Rcpp::export]]
std::map<String, int> table_words(CharacterVector x) {
std::setlocale(LC_ALL, "en_US.UTF-8");
// std::setlocale(LC_COLLATE, "en_US.UTF-8"); // also tried this instead of previous line
std::map<String, int> counts;
int n = x.size();
for (int i = 0; i < n; i++) {
counts[x[i]]++;
}
return counts;
}
/*** R
words <- c("casa", "árbol", "zona", "árbol", "casa", "libro")
table_words(words)
*/
returns:
casa libro zona árbol
2 1 1 2
but I want:
árbol casa libro zona
2 2 1 1
关于如何让table_words 将重音“árbol”放在“casa”之前,使用 Rcpp 甚至在 R 中使用base::sort,有什么想法吗?
另外,std::sort(..., std::locale("en_US.UTF-8")) 仅在我的 Linux 机器上使用:gcc 版本 4.8.2 (Ubuntu 4.8.2-19ubuntu1)。它不适用于 Mac 10.10.3:Apple LLVM 版本 6.1.0 (clang-602.0.53)(基于 LLVM 3.6.0svn)。关于我的 Mac 编译器缺少我的 Linux 编译器的任何线索?
这是两台机器的脚本和 sessionInfo:
// [[Rcpp::plugins(cpp11)]]
#include <locale>
#include <clocale>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
std::vector<std::string> sort_words(std::vector<std::string> x) {
std::sort(x.begin(), x.end(), std::locale("en_US.UTF-8"));
return x;
}
// [[Rcpp::export]]
std::map<String, int> table_words(CharacterVector x) {
// std::setlocale(LC_ALL, "en_US.UTF-8"); // tried this instead of next line
std::setlocale(LC_COLLATE, "en_US.UTF-8");
std::map<String, int> counts;
int n = x.size();
for (int i = 0; i < n; i++) {
counts[x[i]]++;
}
return counts;
}
/*** R
words <- c("casa", "árbol", "zona", "árbol", "casa", "libro")
sort_words(words)
table_words(words)
sort(table_words(words), decreasing = T)
output_from_Rcpp <- table_words(words)
sort(names(output_from_Rcpp))
*/
> words <- c("casa", "árbol", "zona", "árbol", "casa", "libro")
> sort_words(words)
[1] "árbol" "árbol" "casa" "casa" "libro" "zona"
> table_words(words)
casa libro zona árbol
2 1 1 2
> sort(table_words(words), decreasing = T)
casa árbol libro zona
2 2 1 1
> output_from_Rcpp <- table_words(words)
> sort(names(output_from_Rcpp))
[1] "árbol" "casa" "libro" "zona"
sessionInfo on linux machine:
R version 3.2.0 (2015-04-16)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04 LTS
locale:
[1] en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.2.0 Rcpp_0.11.6
sessionInfo on Mac:
R version 3.2.1 (2015-06-18)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.10.3 (Yosemite)
locale:
[1] en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] textcat_1.0-3 readr_0.1.1 rvest_0.2.0
loaded via a namespace (and not attached):
[1] httr_1.0.0 selectr_0.2-3 R6_2.1.0 magrittr_1.5 tools_3.2.1 curl_0.9.1 Rcpp_0.11.6 slam_0.1-32 stringi_0.5-5
[10] tau_0.0-18 stringr_1.0.0 XML_3.98-1.3
【问题讨论】:
-
请原谅我的无知,但是
std::sort什么时候采用了第三个参数,它是一个语言环境?std::sort的第三个参数应该是比较两个项目的函数或仿函数,而不是语言环境。 -
@PaulMcKenzie:语言环境是比较两个项目的函子。 en.cppreference.com/w/cpp/locale/locale/operator()
-
对“Rcpp”一无所知,但您是否知道对于
std::map,排序是类型本身的一部分,您需要自定义比较器来启用不同的排序? -
@ChristianHackl 是的,我知道
std::map订购,但我不知道如何让它把带重音的单词和没有重音的单词按顺序排列,这样我就得到了 “árbol” 在 “casa” 之前。回到std::sort,如果我只指定std::sort(x.begin(), x.end(),我会在“árbol”之前得到“casa”,但如果我指定std::sort(x.begin(), x.end(), std::locale("en_US.UTF-8")),我会得到 "casa" 之前的 "árbol",这是我想要的顺序。我的问题是如何在std::map中获得第二个订单(即 "árbol" 在 "casa" 之前)?