Как рассчитать сумму цифр числа в схеме? - PullRequest
3 голосов
/ 15 июня 2011

Я хочу рассчитать сумму цифр числа в схеме.Это должно работать так:

>(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) ... потому что я использую язык racketDrRacket, поэтому я не могу использовать такую ​​функцию, как char->digit.

Кто-нибудь может мне помочь исправить это?

Ответы [ 6 ]

6 голосов
/ 15 июня 2011

Альтернативным методом было бы перебирать цифры с помощью модуля. Я не так привык к схеме синтаксиса, но вот функция, которая работает в Лиспе для неотрицательных целых чисел (и с небольшой работой может охватить десятичные и отрицательные значения):

(defun sum-of-digits(x) 
  (if (= x 0) 0 
      (+ (mod x 10) 
         (sum-of-digits (/ (- x (mod x 10)) 10)))))
1 голос
/ 15 июня 2011

Что-то вроде этого может делать ваши цифры скорее арифметически, чем в виде строки:

(define (digits n)
    (if (zero? n)
        '()
        (cons (remainder n 10) (digits2 (quotient n 10))))

В любом случае, idk, если это то, что вы делаете, но этот вопрос заставляет меня думать о Project Euler.И если это так, вы оцените обе эти функции в будущих задачах.

Выше приведена сложная часть, а остальное:

(foldr + (digits 12345) 0)

ИЛИ

(apply + (digits 1234))

РЕДАКТИРОВАТЬ - я избавился от intLength выше, но на случай, если вы все еще хотите его.

(define (intLength x)
   (define (intLengthP x c)
      (if (zero? x)
          c
          (intLengthP (quotient x 10) (+ c 1))
      )
   )
   (intLengthP x 0))
1 голос
/ 15 июня 2011

Эти # \ 1, # \ 2 вещи являются символами. Я ненавижу RTFM, но документы по Racket здесь действительно хороши. Если вы выделите строку-> list в DrRacket и нажмете F1, вы должны получить окно браузера с кучей полезной информации.

Чтобы не держать тебя в темноте; Я думаю, что, вероятно, я бы использовал функцию "string" как отсутствующий шаг в вашем решении:

(map string (list #\a #\b))

... производит

(list "a" "b")
0 голосов
/ 18 февраля 2018
(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.

0 голосов
/ 18 июня 2011

Это работает, оно основывается на исходном решении для строки -> списка, просто выполняет преобразование в списке символов

(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))))
0 голосов
/ 15 июня 2011

Лучше было бы на самом деле найти цифры и суммировать их. 34%10 дает 4 и 3%10 дает 3. Сумма 3+4.

Вот алгоритм на F # (извините, я не знаю схемы):

let rec sumOfDigits n =
    if n<10 then n
    else (n%10) + sumOfDigits (n/10)
...