5

我试图了解更多关于如何为 R 使用 Rcpp 包的信息。所以我开始使用 Rcpp 测试基本的排序算法。我从这里的 Hadley Wickham 教程开始。

我以这种方式成功地递归地实现了插入排序:

library(Rcpp)

vetor<-sample(100)
vetor
cppFunction("
    NumericVector insertionsortRC(NumericVector vetor, int n) {
        double aux;
        int i;

        if(n>1) {
            insertionsortRC(vetor,n-1);
            aux=vetor[n-1];
            i=n-1;
            while(vetor[i-1]>aux && i>=0 ) {
                vetor[i]=vetor[i-1];
                i--;
                }
            vetor[i]=aux;
            }

        return vetor;
        }
    ")

但是该函数要求 2 个参数,然后我尝试了这种方式:

cppFunction("
    NumericVector insertionsortRC(NumericVector vetor) {
        int n = vetor.size();

        double aux;
        int i;

        if(n>1) {
            vetor.erase(n-1);
            insertionsortRC(vetor);
            aux=vetor[n-1];
            i=n-1;
            while(vetor[i-1]>aux && i>=0 ) {
                vetor[i]=vetor[i-1];
                i--;
                }
            vetor[i]=aux;
            }

        return vetor;
        }
    ")

我认为擦除在这里不是一个好主意,似乎我从内存中删除了元素并且在递归调用之后无法恢复它。我还认为问题可能出在 vetor.erase(n-1); 行,尝试过 vetor.erase(n); 它编译了,但根本没有用。

用 vetor.erase(n); 我在 R 中收到以下错误:

insertsortRC(vetor) * `/usr/lib/R/bin/exec/R' 中的错误:malloc():内存损坏:0x098db548 *

用 vetor.erase(n-1); 它有一个奇怪的输出:

插入排序RC(向量)[1] 3.607393e-313 3.300000e+01 3.100000e+01 8.600000e+01 2.500000e+01 7.000000e+01 [7] 4.000000e+01 8.800000e+01 8.130000e+01 8.130000e+01. 8.500000E+01 8.700000E+01 [13] 3.900000E+01 6.0000E+01 6.400000E+01 1.000000E+01 8.200000E+01 8.900000E+01 [19] 1.400000E 1.500000E+01 9.600000E+01 2.600000E+01 [25] 4.000000E+00 5.400000E+01 2.900000E+01 8.300000E+01 5.500000E+01 6.800000E 1.000000E+02 5.100000E+01 7.0000E+00 5.300000E+01 [37] 9.900000E+01 6.500000E+01 2.300000E+01 9.400000E+01 5.700000E 4.700000e+01 1.600000e+01 5.000000e+01 2.800000e+01 3.000000e+00 [49] 9.800000e+01 1.100000e+01 1.800000e+01 7.600000e+01 6.300000e+01 7.700000e+01 [55] 7.400000e+01 4.900000e+01 8.000000e+00 9.700000e+01 1.200000e+01 2.700000e+01 [61] 3.500000e+01 7.900000e+01 8.000000e+01 2.000000 E+01 6.700000E+01 9.300000E+01 [67] 5.000000E+00 5.600000E+01 9.0000EE+00 3.700000E+01 2.400000E+01 9.200000E E+01 1.700000E+01 4.600000E+01 4.300000E+01 [79] [79] 3.400000E+01 1.900000E+01 2.000000E+00 9.500000E+01 7.200000E E+01 6.200000E+01 2.200000E+01 4.200000E+01 2.100000E+01 [91] 8.400000E+01 4.800000E+01 7.800000E+01 7.300000E+01 7.300000E+01 3.000000E e+01 5.200000e+01 7.500000e+01700000e+01 [61] 3.500000e+01 7.900000e+01 8.000000e+01 2.000000e+01 6.700000e+01 9.300000e+01 [67] 5.000000e+00 5.600000e+01 9.000000e+00 3.700000e+01 2.400000 E+01 9.200000E+01 [73] 6.900000E+01 3.800000E+01 4.400000E+01 1.700000E+01 4.600000E+01 4.300000E+01 [79] [79] 3.400000E+01 1.900000E+01 1.900000E+01 2.0000E+01 2.0000E+00 9.50000 00 9.500000 E+01 7.200000E+01 1.0000E+00 [85] 6.100000E+01 4.100000E+01 6.200000E+01 2.200000E+01 4.200000E+01 2.100000E e+01 7.300000e+01 3.000000e+01 5.900000e+01 [97] 5.800000e+01 5.200000e+01 7.500000e+01700000e+01 [61] 3.500000e+01 7.900000e+01 8.000000e+01 2.000000e+01 6.700000e+01 9.300000e+01 [67] 5.000000e+00 5.600000e+01 9.000000e+00 3.700000e+01 2.400000 E+01 9.200000E+01 [73] 6.900000E+01 3.800000E+01 4.400000E+01 1.700000E+01 4.600000E+01 4.300000E+01 [79] [79] 3.400000E+01 1.900000E+01 1.900000E+01 2.0000E+01 2.0000E+00 9.50000 00 9.500000 E+01 7.200000E+01 1.0000E+00 [85] 6.100000E+01 4.100000E+01 6.200000E+01 2.200000E+01 4.200000E+01 2.100000E e+01 7.300000e+01 3.000000e+01 5.900000e+01 [97] 5.800000e+01 5.200000e+01 7.500000e+01400000E+01 1.700000E+01 4.600000E+01 4.300000E+01 [79] 3.400000E+01 1.900000E+01 2.000000E+00 9.500000E+01 7.200000E E+01 6.200000E+01 2.200000E+01 4.200000E+01 2.100000E+01 [91] 8.400000E+01 4.800000E+01 7.800000E+01 7.300000E+01 7.300000E+01 3.000000E e+01 5.200000e+01 7.500000e+01400000E+01 1.700000E+01 4.600000E+01 4.300000E+01 [79] 3.400000E+01 1.900000E+01 2.000000E+00 9.500000E+01 7.200000E E+01 6.200000E+01 2.200000E+01 4.200000E+01 2.100000E+01 [91] 8.400000E+01 4.800000E+01 7.800000E+01 7.300000E+01 7.300000E+01 3.000000E e+01 5.200000e+01 7.500000e+01

有人可以告诉我: 01. 是否可以像这样使用 Rcpp 和 R 来实现这个代码,只用一个参数调用函数,数据向量?02.如何正确做?

4

3 回答 3

6

简要地:

  1. 好消息是你的编译工作正常了。

  2. 不太好的消息是段错误。您的代码中可能存在逻辑错误。

  3. 一般来说,添加或删除 NumericVector 等是一个坏主意。这些是浅类型,直接连接到同一对象的 R 内存(“无副本”)。这意味着扩展或移除成本很高。考虑使用 STL std::vector<double>。所有这些都有记录。

于 2013-10-20T03:30:43.217 回答
4

一些东西:

vetor.erase(n)是未定义的行为。第一个索引是0,最后一个是n-1erase不做边界检查,因为每个人都必须付出代价。相反,它假定正确使用该函数,因为在 C++ 世界中很常见。

了解std::sort. 它可能比家庭支持的排序实现更有效,尤其是插入排序。

Rcpp 向量有一个sort方法。所以 aNumericVector可以自行排序。

了解属性,即使用Rcpp-attributes小插图,这更易于使用,这将为您提供一种处理默认参数的方法。

于 2013-10-20T08:53:55.013 回答
0

尝试:vector.erase(vector.begin()+desiredElement)

那应该可以解决您的问题。

NumericVector 类型似乎std::vector至少与它处理数据插入和删除的方式有关,这意味着您必须使用迭代器(但是,我不是 Rcpp 专家)。

布赖恩

于 2014-04-25T01:30:40.723 回答