我正在尝试编写一些简单的Rcpp代码示例.使用Rcpp和inline包装非常容易.
但我很难过如何测试两个字符元素是否相等.以下示例比较了两个字符向量的第一个元素.但我无法编译.
诀窍是什么?
library(Rcpp)
library(inline)
cCode <- '
Rcpp::CharacterVector cx(x);
Rcpp::CharacterVector cy(y);
Rcpp::LogicalVector r(1);
r[0] = (cx[0] == cy[0]);
return(r);
'
cCharCompare <- cxxfunction(signature(x="character", y="character"),
plugin="Rcpp", body=cCode)
cCharCompare("a", "b")
Run Code Online (Sandbox Code Playgroud)
-
==如果两个元素中的一个是常数,则使用的比较完全正常.以下代码编译并给出预期结果:
cCode <- '
Rcpp::CharacterVector cx(x);
Rcpp::LogicalVector r(1);
r[0] = (cx[0] == "a");
return(r);
'
cCharCompareA <- cxxfunction(signature(x="character"), plugin="Rcpp", body=cCode)
cCharCompareA("a")
[1] TRUE
cCharCompareA("b")
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
Rom*_*ois 15
等式运算符已在Rcpp0.10.4中引入.该实现在string_proxy类中如下所示:
bool operator==( const string_proxy& other){
return strcmp( begin(), other.begin() ) == 0 ;
}
Run Code Online (Sandbox Code Playgroud)
所以现在我们可以写:
#include <Rcpp.h>
using namespace Rcpp ;
// [[Rcpp::export]]
LogicalVector test( CharacterVector x, CharacterVector y){
Rcpp::LogicalVector r(x.size());
for( int i=0; i<x.size(); i++){
r[i] = (x[i] == y[i]);
}
return(r);
}
Run Code Online (Sandbox Code Playgroud)
在我们的单元测试中使用类似的东西:
> test(letters, letters)
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Run Code Online (Sandbox Code Playgroud)
koh*_*ske 14
试试这个:
// r[0] = (cx[0] == cy[0]);
// r[0] = ((char*)cx[0] == (char*)cy[0]); <- this is wrong
r[0] = (*(char*)cx[0] == *(char*)cy[0]); // this is correct.
Run Code Online (Sandbox Code Playgroud)
这不容易解释,但是
CharacterVector不是char[].operator []回报StringProxy.StringProxy不是一种类型char.StringProxy有一个char*转换StringProxy为的成员运算符函数char*.所以,也许(char*)cx[0]是一个指针.现在我忘记了很多关于C++语法的事情......
究其原因HY编译失败的类型推断的运算符重载失败==了StringProxy.
Dir*_*tel 12
@kohske非常好(技术性)答案,但这里有更多的C++ - ish:只是比较字符串!
library(inline) ## implies library(Rcpp) when we use the plugin
cCode <- '
std::string cx = Rcpp::as<std::string>(x);
std::string cy = Rcpp::as<std::string>(y);
bool res = (cx == cy);
return(Rcpp::wrap(res));
'
cCharCompare <- cxxfunction(signature(x="character", y="character"),
plugin="Rcpp", body=cCode)
cCharCompare("a", "b")
Run Code Online (Sandbox Code Playgroud)
如果你真的要比较只是字符串的第一个字符,那么你可以从去x到x.c_str(),要么指数的初始元素,或者只是解引用指针的第一个字符.
更多的R-ish答案可能会扫过实际的字符串向量...