Scheme number to list

∥☆過路亽.° 提交于 2019-12-02 01:36:27

问题


I need a subroutine for my program written in scheme that takes an integer, say 34109, and puts it into a list with elements 3, 4, 1, 0, 9. The integer can be any length. Does anyone have a trick for this? I've thought about using modulo for every place, but I don't think it should be that complicated.


回答1:


The simplest way I can think of, is by using arithmetic operations and a named let for implementing a tail-recursion:

(define (number->list num)
  (let loop ((num num)
             (acc '()))
    (if (< num 10)
        (cons num acc)
        (loop (quotient num 10)
              (cons (remainder num 10) acc)))))

Alternatively, you can solve this problem using string operations:

(define char-zero (char->integer #\0))

(define (char->digit c)
  (- (char->integer c) char-zero))

(define (number->list num)
  (map char->digit
       (string->list (number->string num))))

This can be compressed into a single function, but I believe it's easier to understand if we split the problem in subparts as above.

(define (number->list num)
  (map (lambda (c) (- (char->integer c) (char->integer #\0)))
       (string->list
        (number->string num))))

Anyway, the results are as expected:

(number->list 34109)
> '(3 4 1 0 9)



回答2:


Something like this:

(define (num2list-helper num lst)
  (cond ((< num 10) (cons num lst))
        (else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))

(define (num2list num)
  (num2list-helper num '()))

(num2list 1432)

As itsbruce commented you can hide helper function inside main one:

(define (num2list num)
  (define (num2list-helper num lst)
    (cond ((< num 10) (cons num lst))
          (else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))

    (num2list-helper num '()))

(num2list 1432)

to be continued...




回答3:


I'm not a fan of manual looping, so here's a solution based on unfold (load SRFI 1 and SRFI 26 first):

(define (digits n)
  (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))

This returns an empty list for 0, though. If you want it to return (0) instead, we add a special case:

(define (digits n)
  (case n
   ((0) '(0))
   (else (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))))

Of course, you can generalise this for other bases. Here, I implement this using optional arguments, so if you don't specify the base, it defaults to 10:

(define (digits n (base 10))
  (case n
   ((0) '(0))
   (else (unfold-right zero? (cut modulo <> base) (cut quotient <> base) n))))

Different Scheme implementations use different syntaxes for optional arguments; the above uses Racket-style (and/or SRFI 89-style) syntax.



来源:https://stackoverflow.com/questions/12834562/scheme-number-to-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!