使用'which'

时间:2015-07-08 11:57:03

标签: r sieve-of-eratosthenes

我试图定义一个函数,生成所有素数直到n。 我提出了以下解决方案,我将其与solution readily available进行了比较(以下给出以供参考)。基本上两个代码中只有一行差异(如下所示)

sieve <- function(n){
sq.n <- sqrt(n)
vec <- 2:n
primes <- rep(0, times=(sq.n))
i <- 1
while (!(is.na(primes[i] < sq.n)) && (primes[i]) < (sq.n)) {
    primes[i] <- vec[1]
    vec <- vec[which(vec%%primes[i] != 0)] # This keeps all the numbers not divisible by 
    # the prime in question
    i <- i + 1
}
return(c(primes[which(primes!=0)], vec))
}

对效率感到好奇,谷歌搜索产生了以下代码 -

getPrimeNumTilln <- function(n) {
a <- c(2:n)
l <- 2
r <- c()
while (l*l < n) {
    r <- c(r,a[1])
    a <- a[-(which(a %% l ==0))] # This removes all the numbers which are 
    # divisible by the prime in question
    l <- a[1]
}
c(r,a)
}

两种解决方案都可以正常工作。 (如果n是素数的平方,互联网解决方案会给出错误的答案,但这可以很容易地纠正)

这些是微基准测试结果 -

microbenchmark(sieve(100),getPrimeNumTilln(100),times=100)
Unit: microseconds
                  expr     min      lq      mean  median      uq     max neval
            sieve(100) 142.107 153.106 165.85155 162.785 165.425 466.795   100
 getPrimeNumTilln(100)  41.797  47.076  51.09312  49.276  51.036 126.269   100

我想了解这两个函数的运行时间的公平差异

1 个答案:

答案 0 :(得分:4)

第一个函数的循环对n = 100执行10次迭代,第二个函数执行4次迭代。

sieve <- function(n){
  sq.n <- sqrt(n)
  vec <- 2:n
  primes <- rep(0, times=(sq.n))
  i <- 1
  while (!(is.na(primes[i] < sq.n)) && (primes[i]) < (sq.n)) {
    count <<- count + 1
    primes[i] <- vec[1]
    vec <- vec[which(vec%%primes[i] != 0)] # This keeps all the numbers not divisible by 
    # the prime in question
    i <- i + 1
  }
  return(c(primes[which(primes!=0)], vec))
}

count <- 0
sieve(100)
#[1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
count
#[1] 10

getPrimeNumTilln <- function(n) {
  a <- c(2:n)
  l <- 2
  r <- c()
  while (l*l < n) {
    count <<- count + 1
    r <- c(r,a[1])
    a <- a[-(which(a %% l ==0))] # This removes all the numbers which are 
    # divisible by the prime in question
    l <- a[1]
  }
  c(r,a)
}

count <- 0
getPrimeNumTilln(100)
# [1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
count
#[1] 4