2

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

Ps:我不是在帮助他的硬件,我是为自己做的。我喜欢挑战。

4

4 回答 4

3

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

于 2012-09-06T18:34:57.090 回答
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))))))
于 2012-09-06T19:47:22.100 回答
1

这是一种可能的方法:将参数转换为字符列表,并计算与作为参数接收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
于 2012-09-06T19:30:43.987 回答
0

将数字转换为列表,然后找出数字出现在数字中的次数。将数字转换为列表请参阅此示例。

于 2012-09-06T18:34:39.727 回答