2015-02-07 84 views
-2

我有一个递归函数,它将树中的某些节点打印为整数ID。将函数导出到R之后,我不能使用cout输出作为任何事情(或者看起来如此)。如果(1)我可以将输出作为向量返回,或者(2)在R中解析cout而不会失去太多速度,那么理想情况是什么。在递归函数中收集cout或输出为向量

我会在这里插入一些代码,但我的功能是特别通用的。基本上,我试图返回斐波那契数列作为向量而不是总和,而是通过递归函数返回,而不使用全局或静态变量。提前

[1] 0 1 1 2 3 5 

所以一个可能,

y <- fib(6) 

y[4]y[4:5]将分别返回,

[1] 2 

[1] 2 3 

感谢:

例如,fib(6)将内部R返回作为见解和解决问题的想法。使用静态变量就我自己而言。

+0

http://stackoverflow.com/a/6808564/1412059 – Roland 2015-02-07 16:34:48

+0

你的意思“计数”在两个地方还是“cout”艺术术语?只是想知道 – lawyeR 2015-02-07 16:35:35

+0

@lawyeR不,他的意思是'cout'。去谷歌上查询。 (我认为你不能把它看作是R的返回值,但我可能是错的。) – Roland 2015-02-07 16:37:18

回答

1

你应该阅读在线图书http://adv-r.had.co.nz/,而且大多在那里你的问题是部分回答http://adv-r.had.co.nz/Function-operators.html的记忆化部分:

只需添加功能fib3如:

library(memoise) 

fib2 <- memoise(function(n) { 
    if (n < 2) return(1) 
    fib2(n - 2) + fib2(n - 1) 
}) 

fib3 <- memoise(function(n) sapply(1:n, fib2)) 

#> fib3(6) 
#[1] 1 2 3 5 8 13 
3

我详尽的讨论这个问题在Rcpp book的第一章中,R和C++都实现了不同的哈希和记忆实现。

1

只是为了好玩,使用std::generate_n一个稍微复杂的方法和替代函数对象(fseq)的sapply:这些功能进行了参数化

#include <Rcpp.h> 

struct fseq { 
    public: 
    fseq() { 
     current = 0; 
    } 

    int operator()() { 
     int val = fib(current); 
     current++; 
     return val; 
    } 

    int fib(int n) { 
     if (n==0) return 0; 
     if (n==1) return 1; 
     return fib(n-2) + fib(n-1); 
    } 

    private: 
    int current; 
}; 

// [[Rcpp::export(".fib")]] 
int fib(int n) { 
    if (n==0) return 0; 
    if (n==1) return 1; 
    return fib(n-2) + fib(n-1); 
} 

// [[Rcpp::export]] 
std::vector<int> fib_seq(const int n) { 
    if (n < 1) throw std::invalid_argument("n must be >= 1"); 

    std::vector<int> seq; 
    seq.reserve(n); 

    std::generate_n(std::back_inserter(seq), n, fseq()); 
    return seq; 
} 

library(microbenchmark) 
## 
R> fib_seq(6) 
[1] 0 1 1 2 3 5 

R> all.equal(fib_seq(6),.fib_seq(6)) 
[1] TRUE 

.fib_seq <- function(n) sapply(0:(n-1), .fib) 
## 
R> microbenchmark(
    fib_seq(6),.fib_seq(6), 
    times=1000L,unit="us") 
Unit: microseconds 
     expr min  lq  mean median  uq  max neval 
    fib_seq(6) 1.561 1.9015 3.287824 2.108 2.3430 1046.021 1000 
.fib_seq(6) 27.239 29.0615 35.538355 30.290 32.8065 1108.266 1000 

R> microbenchmark(
    fib_seq(15),.fib_seq(15), 
    times=100L,unit="us") 
Unit: microseconds 
     expr min  lq  mean median  uq  max neval 
    fib_seq(15) 6.108 6.5875 7.46431 7.0795 7.7590 20.391 100 
.fib_seq(15) 57.243 60.7195 72.97281 63.8120 73.4045 231.707 100 

R> microbenchmark(
    fib_seq(28),.fib_seq(28), 
    times=100L,unit="us") 
Unit: microseconds 
     expr  min  lq  mean median  uq  max neval 
    fib_seq(28) 2134.861 2143.489 2222.018 2167.364 2219.400 2650.854 100 
.fib_seq(28) 3705.492 3721.586 3871.314 3745.956 3852.516 5040.827 100 

注以反映您的陈述

例如,FIB(6)将内部R返回为:

[1] 0 1 1 2 3 5