Rcpp Math.Min问题中的R - C ++代码再现

时间:2016-07-08 11:27:25

标签: rcpp levenshtein-distance

我正在尝试重现C++代码,我发现LevenshteinDistance代码static int LevenshteinDistance(string s, string t)

更确切地说,我正在尝试从

开始重现该部分
  return d[n, m];
 }

直到

Math.Min(Math.Min(

但是,我遇到rcpp错误。我不确定min中的翻译是什么。我尝试使用// [[Rcpp::export]] NumericVector LevenshteinDistance(NumericVector s, NumericVector t) { int n = s.size(); int m = t.size(); NumericMatrix d(n+1, m+1); if (n == 0) { return m; } if (m == 0){ return n; } for (int i = 0; i < n; i++) d(i, 0) = i; for (int j = 0; j < m; j++) d(0, j) = j; for (int j = 1; j < m; j++) for (int i = 1; i < n; i++) if (s(i - 1) == t(j - 1)) d(i, j) = d(i - 1, j - 1); //no operation else d(i, j) = min( d(i - 1, j) + 1, //a deletion d(i, j - 1) + 1), //an insertion d(i - 1, j - 1) + 1 //a substitution ); return d(n, m); } ,但它似乎不起作用。任何线索?

d(i, j) = min(

所以用

no matching function

我收到此错误消息:return to_return;

1 个答案:

答案 0 :(得分:3)

确实存在三个问题:

  1. 你有一个错字

    d(i, j) = min(
    d(i - 1, j) + 1,    
    d(i, j - 1) + 1),  //typo here with )
      d(i - 1, j - 1) + 1 
    )
    
  2. 使用std::min() is defined to be between two values e.g. std::min(obj1,obj2)而您正在以min()方式使用R

  3. 所以,

    min(c(1,2,3,4))
    

    但是,C++ definition of std::min要求将其写成:

    std::min(1, std::min(2, std::min(3,4)));
    
    1. 如果您希望忠实于string LevenshteinDistance概念,那么您需要切换值从NumericVector类型进入您的函数的方式到任何一个以下:std::stringstd::vector<std::string>(请参阅Gallery Post: Strings with Rcpp),Rcpp::StringVector(请参阅Gallery Post: Working with Rcpp StringVector)或Rcpp::CharacterVector
    2. 以下就足够了:

      #include <Rcpp.h>
      
      // [[Rcpp::export]]
      int LevenshteinDistance(std::string s,
                              std::string t) {
      
        // Number of elements
        int n = s.size();
        int m = t.size();
        Rcpp::IntegerMatrix d(n+1, m+1);
        Rcpp::Rcout << "n:" << n << ", m:" << m << std::endl;
      
        if (n == 0){
          return m;
        }
      
        if (m == 0){
          return n;
        }
      
        for (int i = 0; i <= n; i++){
          d(i, 0) = i;
        }
      
        // No sense to revisit the (0,0) coordinate
        for (int j = 1; j <= m; j++){
          d(0, j) = j;
        }
      
        for (int j = 1; j <= m; j++){
      
          for (int i = 1; i <= n; i++){
      
            if (s[i - 1] == t[j - 1]){
      
              d(i, j) = d(i - 1, j - 1);  // no operation
      
            } else {
      
              d(i, j) = std::min(d(i - 1, j) + 1,    //a deletion
                                 std::min(d(i, j - 1) + 1,   //an insertion
                                 d(i - 1, j - 1) + 1)); //a substitution
      
            } // end if
      
          } // end inner for
      
        } // end outer for
      
        return d(n, m);
      }
      

      编写此函数后,我们可以选择编写一个快速包装器来处理不同维度的比较,例如多个源到目标等等......

      // [[Rcpp::export]]
      Rcpp::IntegerVector LevenshteinDistance_Vector(std::vector<std::string> s,
                                                     std::string t){
      
        // Number of Sources
        unsigned int sn = s.size();
      
        Rcpp::IntegerVector o(sn); // populates automatically with 0.
      
        for(unsigned int i = 0; i < sn; i++){
          o(i) = LevenshteinDistance(s[i],t);
        }
      
        return o;
      }