如何计算位数?

时间:2013-10-22 23:28:12

标签: scheme racket

  
      
  1. (CountDigits n)采用正整数n,并返回其包含的位数。如,

    (CountDigits 1) → 1
    (CountDigits 10) → 2
    (CountDigits 100) → 3
    (CountDigits 1000) → 4
    (CountDigits 65536) → 5
    
  2.   

我认为我应该使用剩余的数字和其他东西,但其他我真的失去了。我首先尝试的是将数字除以10,然后查看数字是否小于1.如果是,那么它有1位数。如果它不然后除以100,依此类推。但我不确定如何将其扩展到任何数字,所以我废弃了这个想法

(定义(数字位数)   (if(=数字0)       1

3 个答案:

答案 0 :(得分:2)

在评论中进行了一些讨论之后,我们想出了如何使用 x 数字取一个 n 的数字,并获得一个带 x-1的数字 digits:除以10(使用整数除法,即忽略余数)。我们可以通过检查数字是否小于10来检查数字是否只有一位数。现在我们只需要一种方法来表示数字中的总位数作为(递归)函数。有两种情况:

  1. (基本情况)小于10的数字 n 有1位数。所以CountDigits( n )= 1。
  2. (递归情况)大于10的数字 n 具有CountDigits( n )= 1 + CountDigits( n / 10 )。< / LI>

    现在只需要对此进行编码即可。这听起来像是家庭作业,所以我不想放弃一切。你仍然需要弄清楚如何在Scheme中写出条件“ n &lt; 10”,以及“ n / 10”(只是商部分) ,但一般结构是:

    (define (CountDigits n)                       ; 1
      (if [n is less than 10]                     ; 2
          1                                       ; 3
          (+ 1 (CountDigits [n divided by 10])))) ; 4
    

    对这些行的解释,一次一个:

    1. (define (CountDigits n)开始定义名为CountDigits的函数(CountDigits n)
    2. 在Racket中,if用于评估一个表达式,称为测试或条件,然后评估并返回其余两个表达式之一的值。 (if test X Y)评估test,如果test生成 true ,则评估X并返回结果,否则Y评估并返回结果。
    3. 1 n 小于10时要返回的值(上述基本情况)。
    4. 1 + CountDigits(n / 10)是你想要返回的值,否则在Racket(和Scheme,以及一般的Lisp)中它被写为(+ 1 (CountDigits [n divided by 10]))
    5. 熟悉Racket文档的风格是个好主意,因此我将指出相应的章节:3.2.2 Generic Numerics。您需要的功能应该在那里,文档应该提供足够的示例来帮助您弄清楚如何编写缺失的位。

答案 1 :(得分:1)

我知道这已经过时了但是为了将来参考任何发现这个的人,我会这样写:

(define (count-digits n acc)
  (if (< n 10)
    (+ acc 1)
    (count-digits (/ n 10) (+ acc 1))))

不同之处在于这个是尾递归的,并且基本上等同于迭代函数(并且内部的Racket迭代形式实际上利用了这个事实。)

使用跟踪说明了不同之处:

(count-digits-taylor 5000000)
>(count-digits-taylor 5000000)
> (count-digits-taylor 500000) 
> >(count-digits-taylor 50000)
> > (count-digits-taylor 5000)
> > >(count-digits-taylor 500)
> > > (count-digits-taylor 50)
> > > >(count-digits-taylor 5)
< < < <1
< < < 2
< < <3
< < 4
< <5
< 6
<7
7

(count-digits 5000000 0)
>(count-digits 5000000 0)
>(count-digits 500000 1)
>(count-digits 50000 2)
>(count-digits 5000 3)
>(count-digits 500 4)
>(count-digits 50 5)
>(count-digits 5 6)
<7
7

对于这项练习,这并不重要,但这是一种很好的学习方式。当然,由于原始帖子要求一个名为CountDigits的函数,它只需要一个参数(n),你只需添加:

(define (CountDigits n) 
  (count-digits n 0)) 

答案 2 :(得分:1)

偶然发现了这个并且必须提供基于日志的答案:

(define (length n)
    (+ 1 (floor (/ (log n) (log 10))))
)

为清晰起见编辑:这是一个不使用递归的O(1)解决方案。例如,给定

(define (fact n)
  (cond
    [(= n 1) 1]
    [else (* n (fact (- n 1)))]
  )
)

(define (length n)
  (+ 1 (floor (/ (log n) (log 10))))
)

跑步(时间(长度(事实10000)))产生

cpu time: 78 real time: 79 gc time: 47
35660.0

表示10000!产生一个由35660位数组成的答案。