【问题标题】:Applying "while(a[++i] < v )" in R在 R 中应用“while(a[++i] < v)”
【发布时间】:2014-03-06 23:40:37
【问题描述】:

以下 C 代码从给定的左索引和给定的右索引搜索数组 a[],以查找左索引和 i 之间的每个数组值都小于 v 的两个索引(i 和 j) ,并且 j 和右索引之间的每个数组值都大于 v:

i= leftindex - 1 ;
j = rightindex ;
while(TRUE) { 
while( a[++i] < v) ;
while( a[--j] > v) ;
if (i >= j ) { break }
... }

这种结构可以在快速排序算法的各种实现中看到。

我的问题是:当 a 是向量时,以下是在 R 语言中完成相同任务的最有效方法吗?

i = leftindex - 1 ;
j = rightindex ;
v = a[rightindex]
while(TRUE) {
  while (a[i <- i+1] < v ) { }  # R doesn't get the ++ operator
  while (a[j <- j-1] > v) { }   # R doesn't get the -- operator
  if (i >= j ) { break }
  ... 
} 

因此,例如,如果'a'是:

 a <- c('a','s','o','r','t','i','n','g','e','x','a','m','p','l','e') 

...和

left.index = 1; right.index = 15 

...然后在这段代码运行后,我希望 v、i 和 j 的值是:

v = e
i = 2
j = 11

我在 R 中找不到任何定义运算符“++”或“--”的内容。

R 中的优先级是否保证 "a[i

我想在适当的地方对向量 a 应用一个匿名函数(递减和比较),但这样写起来更简单。

任何想法将不胜感激。

【问题讨论】:

  • 我怀疑 whichdiff 的组合可以执行 R 向量操作,这将比 while 循环更有效。为什么不提供一个数据示例和您对正确答案的说明?
  • 好的,谢谢,我编辑了原始问题以包含一个示例。抱歉,我在初始化 j 的代码 sn-p 中有错字,所以我也更正了。

标签: c arrays r operator-precedence


【解决方案1】:

据我了解,您正在尝试用 R 版本替换以下行:

while( a[++i] < v);
while( a[--j] > v);

这两行的简单写法是:

i <- i + min(which(a[(i+1):length(a)] >= v))
j <- max(which(a[1:(j-1)] <= v))

在每种情况下,which 函数都在计算所有索引,其中a 的某个子集具有适当的值,因此它的效率可能低于在自定义 C/C++ 代码中循环直到找到第一个此类条目。

如果效率对您很重要,您可以为此操作编写一个非常简单的Rcpp 函数。在这里,我定义了incrementdecrement,它们执行这两个操作,特别注意将ij(我假设它们在R 代码中为1 索引)转换为0 索引值在 C++ 代码中:

library(Rcpp)
increment <- cppFunction("
  int increment(NumericVector a, int i, const double v) {
    while( a[(++i)-1] < v) ;
    return i;
  }")

decrement <- cppFunction("
  int decrement(NumericVector a, int j, const double v) {
    while( a[(--j)-1] > v) ;
    return j;
  }")

然后您可以将您的两行转换为i &lt;- increment(a, i, v)j &lt;- decrement(a, j, v)

【讨论】:

  • 感谢 Rcpp 参考。我不知道那个包(对 R 世界来说非常新),我会研究它。
  • 我喜欢你的回答。我同意, min(which(...)) 将比 while(..) 进行更多的比较,while(..) 在满足标准的第一个元素上停止。因为在排序时比较是“领域的硬币”,所以我喜欢最小化它们的想法。
猜你喜欢
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多