【问题标题】:number of times a digit appear数字出现的次数
【发布时间】:2012-09-06 18:27:53
【问题描述】:

好的,我上学期参加了scheme,我知道你不可能在一个学期内就这么擅长scheme。一位朋友问我如何计算某个数字出现在一个数字中的次数。如果它是一个列表,我知道该怎么做。起初我认为这是对内置商或余数的简单使用,但最终并没有像我想象的那样。例如,我如何计算数字中出现五的次数:(numfives 125458563) 应该返回 3。感谢任何帮助。

P.s:我不是在帮助他的硬件,我是为自己做这件事。我喜欢挑战。

【问题讨论】:

    标签: scheme racket


    【解决方案1】:

    使用string->list 将字符串转换为字符列表。然后像处理列表一样继续操作,您说您已经知道该怎么做。 (您可以使用各种格式化函数将数字转换为字符串。)

    【讨论】:

      【解决方案2】:

      我不喜欢所有基于字符串的解决方案。

      在我看来,最好的方法是在每个阶段通过除以(和修改)10 来查看每个数字,然后进行比较。示例:

      (define (count-digit num digit)
        (let loop ((num num)
                   (count 0))
          (if (zero? num) count
              (loop (quotient num 10)
                    (+ count (if (= digit (remainder num 10)) 1 0))))))
      

      【讨论】:

      • 对于这种极端情况,上述解决方案将失败:(count-digit 0 0) 它返回零,但正确答案是一。
      • 另外,您正在重新定义内置的count 过程。
      • +1 这也是我的做法,但它不适用于没有 (abs num) 的负数,也不适用于浮点数,其中字符串版本做
      • 如果不是整数怎么办?如果你想使用不同的基地怎么办?这个问题基本上是关于数字的文本表示,因此(IMO)字符串是处理它的最佳方法。
      【解决方案3】:

      这是一种可能的方法:将number参数转换为字符列表,并计算与作为参数接收的digit对应的字符相等的字符数:

      (define (num-digits number digit)
        (let ((n (number->string number))
              (d (integer->char (+ (char->integer #\0) digit))))
          (count (lambda (x) (char=? x d))
                 (string->list n))))
      

      上述过程的另一种写法,更短但更难阅读:

      (define (num-digits number digit)
        (count (curry char=? (integer->char (+ (char->integer #\0) digit)))
               (string->list (number->string number))))
      

      另一种选择是通过算术运算依次处理每个数字,如@ChrisJester-Young 的回答,但考虑到数字和数字都为零的边缘情况,并避免重新定义内置的count 过程 - 还请记住,这仅适用于 >= 0 且以 10 为底的整数。方法如下:

      (define (num-digits number digit)
        (if (= number digit 0)
            1
            (let loop ((num number)
                       (counter 0))
              (cond ((zero? num)
                     counter)
                    ((= digit (remainder num 10))
                     (loop (quotient num 10) (add1 counter)))
                    (else
                     (loop (quotient num 10) counter))))))
      

      上面的基于字符串的解决方案可能看起来有点笨拙,但编写起来更短,并且具有处理负数、带小数的数字、不同于 10 的基数等的额外优势。无论如何,这将适用于任何版本:

      (num-digits 125458563 5)
      > 3
      

      这将适用于基于字符串的版本:

      (num-digits -123.1234152 1)
      > 3
      

      【讨论】:

      • 48 听起来有点太神奇了。如果它们不在基于 ASCII 的系统上怎么办?最好使用(char->integer #\0)。不过,即使这样也假设所有数字都是连续表示的。
      • 我仍然想知道是否有一个不会对任何数字进行计数,而只是像我的示例一样针对特定数字。 (numfives 255353) 返回 3。我信任他的数学技能的人对我说,不可能找到一个公式。在上述情况下不应该有两个参数(数字,数字)。起初我认为这更容易,但现在听起来更忙了。
      • 好吧,您可以根据更通用的解决方案为每种情况编写一个专门的函数。例如,此过程将只计算五个:(define (numfives number) (num-digits number 5))
      • 哦,我明白你做了什么。好的和简单的方法,没有那样看。在您之前的过程中,您使用了“add1”,我不得不将其更改为 (+ 1)。不知道“add1”在方案中有效。
      【解决方案4】:

      将数字转换为列表,然后找出数字出现在数字中的次数。 用于将数字转换为列表See this example.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-20
        • 2017-07-26
        • 1970-01-01
        相关资源
        最近更新 更多