R语言Codewars实战——Number of trailing zeros of N!(5kyu)

Description:

Write a program that will calculate the number of trailing zeros in a factorial of a given number.

N! = 1 * 2 * 3 * … * N

Be careful 1000! has 2568 digits…

For more info, see: http://mathworld.wolfram.com/Factorial.html

单词说明factorial,adj.因子的, 阶乘的; n. 阶乘

Examples

zeros(6) = 1
# 6! = 1 * 2 * 3 * 4 * 5 * 6 = 720 --> 1 trailing zero

zeros(12) = 2
# 12! = 479001600 --> 2 trailing zeros

Hint: You’re not meant to calculate the factorial. Find another way to find the number of zeros.

单词说明hint,n.暗示, 线索; v.暗示, 示意

Test Cases:

test_that("Fixed tests", {
  expect_equal(zeros(0), 0)
  expect_equal(zeros(6), 1)
  expect_equal(zeros(30), 7)
  expect_equal(zeros(100), 24)
  expect_equal(zeros(1000), 249)
  expect_equal(zeros(100000), 24999)
  expect_equal(zeros(1000000000), 249999998)
})

test_that("Random tests", {
  solution = function(n) {
    r = 0
    while (n > 0) {
      n = n %/% 5
      r = r + n
    }
    r
  }

  for (i in 1:100) {
    n = floor(runif(1, 0, 1001))
    result = solution(n)
    expect_equal(zeros(n), result)
  }
  
  for (i in 1:100) {
    n = floor(runif(1, 1001, 1000001))
    result = solution(n)
    expect_equal(zeros(n), result)
  }
  
  for (i in 1:100) {
    n = floor(runif(1, 1000001, 1000000001))
    result = solution(n)
    expect_equal(zeros(n), result)
  }
})

我的代码

zeros <- function(n){
  ifelse(n<5, 0, n%/%5+Recall(n%/%5))
}

代码当中设计到的原理是这样的:

令f(x)表示正整数x末尾所含有的“0”的个数,则有: 


  ①当0 < n < 5时,f(n!) = 0; 

  ②当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

从而可以递归求解。

讲到递归,不知道有没有人发现我在代码中用到了Recall函数,这种函数讲道理是我新学会的,下面我贴一段R语言帮助文档给出的解释:

Recall {base}

Recursive Calling(递归调用)

Description:
Recall is used as a placeholder for the name of the function in which it is called. It allows the definition of recursive functions which still work after being renamed, see example below.

Examples:

## A trivial (but inefficient!) example:
fib <- function(n)
   if(n<=2) { if(n>=0) 1 else 0 } else Recall(n-1) + Recall(n-2)
fibonacci <- fib; rm(fib)
## renaming wouldn't work without Recall
fibonacci(10) # 55

简单来说,Recall就是替换被递归调用的函数名,我尝试过把上面帮助文档中的Recall换成fib,结果将会完全不一样,会出现这么个错误:Error in fib(n - 1) : 没有"fib"这个函数,原因是代码中把fib赋给fibonacci之后又把它给删了,所以在递归调用的时候调不到fib,从而导致出问题。但如果把递归函数中的fib换为Recall却可以正常调用,也就是说提高了函数的稳定性与可用性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三只佩奇不结义

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值