2011-10-24 3 views
12

간단한 Rcpp 코드 예제를 작성하려고합니다. 이것은 Rcppinline 패키지를 사용하면 매우 쉽습니다.Rcpp :: CharacterVector 요소가 동일한 지 테스트하는 방법은 무엇입니까?

하지만 두 문자 요소가 동일한 지 여부를 테스트하는 방법에 난처한 생각이납니다. 다음 예제에서는 두 문자 벡터의 첫 번째 요소를 비교합니다. 하지만 컴파일 할 수는 없습니다.

트릭이란 무엇입니까?

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") 

-

두 요소 중 하나가 일정하면 완벽하게 정상적으로 == 작품을 사용하여 비교. 다음 코드는 컴파일 준다 예상 결과 :

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 
+0

어디'시험이다 구현은 string_proxy 클래스에서 다음과 같습니다 '정의 되었습니까? – James

+0

왜 cxxfunction을 사용하여 설정하기 전에 NULL로 설정 했습니까? – Spacedman

+0

@James 사과 -'cx [0] == cy [0]'- 편집해야합니다. – Andrie

답변

11

@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") 

는, 당신은 x에서 x.c_str() 인덱스 초기 요소, 또는 단지 첫 번째 문자에 대한 포인터 역 참조 중 하나에 갈 수 있습니다. 더 R-틱 대답은 아마도 문자열의 실제 벡터를 통해 청소 수

...

+0

이 주셔서 감사합니다 - 그것은 가장 도움이 내 진짜 문제는 벡터 석권 물론이다. 하지만 최소한의 재현 예를 얻으려고, 나는 내 문제는 즉 CharacterVector의 개별 요소를 비교하는 비교 문자열에 있음을 깨달았다.이 비트가 해결,이에 정의 된 벡터 연산을 사용하여 최대 단계로 솔직해야한다 'Rcpp :: Sugar' – Andrie

+0

* Rcpp 설탕 * 공상 가기 전에 (NO : 여기에는 클래스 설탕이 없기 때문에) 내가 처음 루프와 구식를 시도 할 것 –

+0

감사합니다 -.. 그것은 루프 작동이 에스. – Andrie

13

이 시도 :

// 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. 

설명하기 쉽지 않지만

  1. CharacterVectorchar[] 없습니다.
  2. operator []StringProxy을 반환합니다.
  3. StringProxychar이 아닙니다.
  4. StringProxy에는 StringProxychar*으로 변환하는 멤버 연산자 함수 char*이 있습니다.

따라서 (char*)cx[0]은 포인터입니다. 는 지금은 컴파일이 실패

이유 HY는 StringProxy에 대한 연산자 오버로드 ==의 형식 유추의 실패입니다 ... C++ 구문에 대한 많은 것을 잊는다.

+0

+1 감사합니다. 그리고 설명에 감사드립니다. . (I이 라인을 따라 Rcpp' 설탕 '의 비트가 의심'난 char''로 강제 다양한 형태를 시도했지만, 애매 대답 '숯 *를 이용하여 억압이었다'등 (CX [0]) '-... 희망 누군가가 언급하고 올바른 'Rcpp' 설탕 구문을 제공 – Andrie

+0

을 @Andrie에게 첫 번째 버전을 할 수가 잘못된 현재 버전이 올바른지는 – kohske

12

항등 연산자는 Rcpp 0.10.4에 도입되었습니다.

#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); 
} 

을 그리고 비슷한 일이 우리의 단위 테스트에 사용됩니다 : 지금 우리가 쓸 수 그래서

bool operator==(const string_proxy& other){ 
    return strcmp(begin(), other.begin()) == 0 ; 
} 

:

> 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 
+0

이것은 좋은 일입니다. 불필요한 사본을 절약 할 수 있습니다. – Sameer

관련 문제