我想计算Scheme中数字的位数总和。它应该像这样工作:
>(sum-of-digits 123)
6
我的想法是将数字123
转换为字符串"123"
,然后将其转换为列表'(1 2 3)
,然后使用(apply + '(1 2 3))
获取6
。
但不幸的是,它没有像我想象的那样工作。
>(string->list(number->string 123))
'(#\1 #\2 #\3)
显然'(#\1 #\2 #\3)
与'(1 2 3)
不同...因为我在DrRacket下使用语言racket
,所以我不能使用像char->digit
这样的函数。
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:6)
另一种方法是使用modulo循环数字。我不习惯使用语法,但是这里有一个在Lisp中用于非负整数的函数(并且有一点工作可以包含小数和负值):
(defun sum-of-digits(x)
(if (= x 0) 0
(+ (mod x 10)
(sum-of-digits (/ (- x (mod x 10)) 10)))))
答案 1 :(得分:1)
那些#\ 1,#\ 2的东西都是字符。我讨厌RTFM你,但Racket docs在这里真的很棒。如果你在DrRacket中突出显示string->列表并点击F1,你应该得到一个包含大量有用信息的浏览器窗口。
为了不让你陷入黑暗;我想我可能会使用“字符串”功能作为解决方案中缺少的步骤:
(map string (list #\a #\b))
...生产
(list "a" "b")
答案 2 :(得分:1)
像这样的东西可以算术上的数字而不是字符串样式:
(define (digits n)
(if (zero? n)
'()
(cons (remainder n 10) (digits2 (quotient n 10))))
无论如何,idk如果你正在做什么,但这个问题让我想到Project Euler。如果是这样,您将在未来的问题中欣赏这两个功能。
以上是困难的部分,其余部分是:
(foldr + (digits 12345) 0)
OR
(apply + (digits 1234))
编辑 - 我摆脱了intLength
以上,但万一你还想要它。
(define (intLength x)
(define (intLengthP x c)
(if (zero? x)
c
(intLengthP (quotient x 10) (+ c 1))
)
)
(intLengthP x 0))
答案 3 :(得分:0)
更好的想法是实际找到数字并求它们。 34%10
提供4
,3%10
提供3
。总和为3+4
。
这是F#中的算法(对不起,我不知道Scheme):
let rec sumOfDigits n =
if n<10 then n
else (n%10) + sumOfDigits (n/10)
答案 4 :(得分:0)
这是有效的,它建立在您的初始字符串 - &gt;列表解决方案上,只是对字符列表进行转换
(apply + (map (lambda (d) (- (char->integer d) (char->integer #\0)))
(string->list (number->string 123))))
可以将转换函数考虑在内以使其更清晰:
(define (digit->integer d)
(- (char->integer d) (char->integer #\0)))
(apply + (map digit->integer (string->list (number->string 123))))
答案 5 :(得分:-1)
(define (sum-of-digits num)
(if (< num 10)
num
(+ (remainder num 10) (sum-of-digits (/ (- num (remainder num 10)) 10)))))
递归过程..终止于n < 10
,其中sum-of-digits
返回输入num
本身。