R规划效率&一个数的阶乘分解
我正试图从代码战中解出一个kata,叫做R中的阶乘分解。kata的目的是分解n!(阶乘n)转化为它的素因子。函数应该返回一个字符串,如 反编译(12)->“2^10*3^5*5^2*7*11” 我能够解决它,但达到了服务器超时(通过74个任务)。我试图对它进行一些优化(pointwise()的lappy),但我无法更改基本内核(对于while循环) 任何帮助都将不胜感激,因为我已经投入了比我应该投入的更多的时间R规划效率&一个数的阶乘分解,r,performance,factorial,R,Performance,Factorial,我正试图从代码战中解出一个kata,叫做R中的阶乘分解。kata的目的是分解n!(阶乘n)转化为它的素因子。函数应该返回一个字符串,如 反编译(12)->“2^10*3^5*5^2*7*11” 我能够解决它,但达到了服务器超时(通过74个任务)。我试图对它进行一些优化(pointwise()的lappy),但我无法更改基本内核(对于while循环) 任何帮助都将不胜感激,因为我已经投入了比我应该投入的更多的时间 ##' A function for a factorial decompositi
##' A function for a factorial decomposition of a number
##' @title decomp
##' @param n integer
##' @return a String with the factorial decomposition
##' @author krisselack
decomp <- function(n) {
# https://stackoverflow.com/questions/19767408/prime-number-function-in-r
is.prime <- function(n) n == 2L || all(n %% 2L:ceiling(sqrt(n)) != 0)
p <- 2:n
primes <- p[as.logical(vapply(p, is.prime, 1))]
erg <- NULL
pointwise <- function(x) {
primloop <- primes[primes<=x]
for(j in primloop){
while(x %% j == 0){
x <- x/j
erg <- c(erg, j)
}
}
if(length(erg)>0)
return(erg)
}
erg2 <- unlist(lapply(p, pointwise))
ergfin <- table(erg2)
namen <- paste(ifelse(ergfin>1, paste0(names(ergfin), "^", ergfin),
paste(names(ergfin))),
collapse = " * ")
return(namen)
}
decomp(5) # -> "2^3 * 3 * 5"
decomp(12) # -> "2^10 * 3^5 * 5^2 * 7 * 11"
decomp(17) # -> "2^15 * 3^6 * 5^3 * 7^2 * 11 * 13 * 17"
decomp(25) # -> "2^22 * 3^10 * 5^6 * 7^3 * 11^2 * 13 * 17 * 19 * 23"
一个数的阶乘分解函数
##“@title decomp
##“@param n integer
##“@返回具有阶乘分解的字符串
##“@作者krisselack
分解
但我不想麻烦了:真正的瓶颈将是众所周知的缓慢的字符串粘贴
在我的笔记本电脑上,
decomp2(10e5)
需要几秒钟,而decomp2(10e6)
大约需要2分钟。我99%确定字符串粘贴实际上是这种情况下的瓶颈。您可以使用包{primefactr}来实现这一点:
> primefactr::ReducePrime(c(rep(0, 999), 1), out.summary = TRUE)
[,1] [,2]
primes 2 5
power 3 3
> primefactr::ReducePrime(c(rep(0, 9999), 1), out.summary = TRUE)
[,1] [,2]
primes 2 5
power 4 4
> primefactr::ReducePrime(c(rep(0, 999999), 1), out.summary = TRUE)
[,1] [,2]
primes 2 5
power 6 6
仅供参考,
decomp(1000)
在我的笔记本电脑上立即运行,decomp(10000)
不到2秒。你知道它超时的数量级吗?谢谢。与其他Kata一起进行了大约100-120次测试。我通过了65-75次测试。服务器时间最长为12秒。你知道是什么使它超时或隐藏了吗?至少对我来说它是隐藏的。这里是kata的链接:您可能可以通过另一种方式来提高性能:循环2到n之间的素数,并计算出它们在阶乘中有多少因子。不过,您必须处理多重性。因此,现在,复制粘贴您的解决方案:时间:6629ms经过:90失败:0。那是90次测试,我通过了75次。谢谢。我以前没有用过purr。你不必用purr
:vapply
实际上是一样的。公平地说,您的代码在运行算法时是高效的。这不是真正的代码改进,而是另一种算法!我的程序只考虑比当前数字小的素数,但没有考虑1:n本身的可分解性。我羞愧地收获了业力,但通过这次练习我学到了很多。感谢您快速而熟练的帮助!
Unit: microseconds
expr min lq mean median uq max neval
sieve 395.010 405.4015 423.2184 410.8445 439.629 584.71 100
naive_filter 2875.782 2936.5195 3268.4576 2979.4925 3016.060 16875.81 100
> primefactr::ReducePrime(c(rep(0, 999), 1), out.summary = TRUE)
[,1] [,2]
primes 2 5
power 3 3
> primefactr::ReducePrime(c(rep(0, 9999), 1), out.summary = TRUE)
[,1] [,2]
primes 2 5
power 4 4
> primefactr::ReducePrime(c(rep(0, 999999), 1), out.summary = TRUE)
[,1] [,2]
primes 2 5
power 6 6