0

我正在尝试在 R 中编写一个简单的函数来计算一个数字的所有除数。这就是我想要输出的方式:

> divisors(21)
[1] 1 3 7 21

我是初学者,从下面的代码开始。但是我认为这是完全错误的,因为它根本不起作用。

divisors <- function(number) {
  x <- c(1:number)
  for(i in 1:number){
    if(number/i == c(x)) {
      paste(i)
    }
  }
  return(i)
}
divisors(10)
4

2 回答 2

11

这个怎么样...

divisors <- function(x){
  #  Vector of numberes to test against
  y <- seq_len(x)
  #  Modulo division. If remainder is 0 that number is a divisor of x so return it
  y[ x%%y == 0 ]
}

divisors(21)
#[1]  1  3  7 21

divisors(4096)
#[1]    1    2    4    8   16   32   64  128  256  512 1024 2048

当然,数字越大,效率就越重要。你可能想seq_len(x)用类似的东西替换......

seq_len( ceiling( x / 2 ) )

这仅适用于正自然数。

更新:使用 Rcpp 的旁白

#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
IntegerVector divCpp( int x ){
  IntegerVector divs = seq_len( x / 2 );
  IntegerVector out(0);
  for( int i = 0 ; i < divs.size(); i++){
    if( x % divs[i] == 0 )
      out.push_back( divs[i] );
  }
  return out;
}

给出相同的结果:

identical( divCpp( 1e6 ) , divisors( 1e6 ) )
#[1] TRUE

针对基本 R 函数运行...

require( microbenchmark )
bm <- microbenchmark( divisors(1e6) , divCpp(1e6) )
print( bm , unit = "relative" , digits = 3 , order = "median" )

#Unit: relative
#            expr  min   lq median   uq  max neval
#   divCpp(1e+06) 1.00 1.00   1.00 1.00  1.0   100
# divisors(1e+06) 8.53 8.73   8.55 8.41 11.3   100
于 2013-10-19T11:56:03.617 回答
1

或者 gmp::factorize,在其他现有工具中。

我经常发现查看已发布软件包的源代码以获取执行类似任务的好主意很方便。

于 2013-10-19T12:33:41.787 回答