gpt4 book ai didi

c++ - 在 Rcpp 中用(西类牙语)重音词对 map 进行排序

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:45:27 26 4
gpt4 key购买 nike

虽然我可以通过在 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"

我不知道如何用 map 做同样的事情:

// 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 使用 Rcpp 将带重音的“árbol”放在“casa”之前,或者甚至在 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 编译器有什么的任何线索?

对于两台机器,这是我的脚本和我的 session 信息:

// [[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::map 上应用 std::sort 没有意义,因为 ma​​p 总是排序,根据定义。该定义是模板实例化的具体类型的一部分。 std::map 具有第三个“隐藏”类型参数,用于用于对键进行排序的比较函数,键类型默认为 std::less。参见 http://en.cppreference.com/w/cpp/container/map .

在你的情况下,你可以使用 std::locale 作为比较类型,并传递 std::locale("en-US") (或任何合适的你的系统)到构造函数。

这是一个例子。它使用 C++11,但您可以在 C++03 中轻松使用相同的解决方案。

#include <map>
#include <iostream>
#include <string>
#include <locale>
#include <exception>

using Map = std::map<std::string, int, std::locale>;

int main()
{
try
{
Map map(std::locale("en-US"));
map["casa"] = 1;
map["árbol"] = 2;
map["zona"] = 3;
map["árbol"] = 4;
map["casa"] = 5;
map["libro"] = 6;

for (auto const& map_entry : map)
{
std::cout << map_entry.first << " -> " << map_entry.second << "\n";
}
}
catch (std::exception const& exc)
{
std::cerr << exc.what() << "\n";
}
}

输出:

árbol -> 4
casa -> 5
libro -> 6
zona -> 3

当然,您必须意识到 std::locale 高度依赖于实现这一事实。 Boost.Locale 你可能会过得更好.

另一个问题是这个解决方案可能看起来令人困惑,因为 std::locale 并不是许多程序员会与比较函数相关联的东西。这几乎有点太聪明了。

因此一个可能更具可读性的替代方案:

#include <map>
#include <iostream>
#include <string>
#include <locale>
#include <exception>

struct ComparisonUsingLocale
{
std::locale locale{ "en-US" };

bool operator()(std::string const& lhs, std::string const& rhs) const
{
return locale(lhs, rhs);
}
};

using Map = std::map<std::string, int, ComparisonUsingLocale>;

int main()
{
try
{
Map map;
map["casa"] = 1;
map["árbol"] = 2;
map["zona"] = 3;
map["árbol"] = 4;
map["casa"] = 5;
map["libro"] = 6;

for (auto const& map_entry : map)
{
std::cout << map_entry.first << " -> " << map_entry.second << "\n";
}
}
catch (std::exception const& exc)
{
std::cerr << exc.what() << "\n";
}
}

关于c++ - 在 Rcpp 中用(西类牙语)重音词对 map 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31498002/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com