【问题标题】:Writing a function to calculate divisors in R [duplicate]编写一个函数来计算R中的除数
【发布时间】:2013-10-19 11:50:54
【问题描述】:

我正在尝试在 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)

【问题讨论】:

  • 所以你只想要素因数,对吧?真的你应该做更多的搜索。

标签: r function


【解决方案1】:

这个怎么样...

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

【讨论】:

    【解决方案2】:

    gmp::factorize 以及其他现有工具。

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

    【讨论】:

    • 肯定更多评论?
    • @SimonO101 好吧,它很短,但它是一个答案。这是一条很好的线....
    • 是的。我在看你的网站。有兴趣!!漂亮的弹球机:-)
    • 这不给出数字的因数,只给出素数分解。例如。对于 n = 75600,当因子/除数超过 100 个时,factorize(n) 返回 2 2 2 2 3 3 3 5 5 7。
    • @JosephWood OTOH,一旦你有了质因数分解,只需创建相同的所有组合,使用标准 R 工具非常容易。
    猜你喜欢
    • 1970-01-01
    • 2021-11-22
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 2019-12-07
    相关资源
    最近更新 更多