开发者

how to convert a list to num in scheme?

开发者 https://www.devze.com 2022-12-10 20:48 出处:网络
开发者_StackOverflow中文版like convert (1 2 3 4) to 1234~The problem is characterized by coalescing a list into a single value, strongly suggesting use of a fold:
开发者_StackOverflow中文版

like convert (1 2 3 4) to 1234~


The problem is characterized by coalescing a list into a single value, strongly suggesting use of a fold:

(define (fold-left op initial items)
  (define (loop result rest)
    (if (null? rest)
        result
        (loop (op result (car rest))
              (cdr rest))))
  (loop initial items))

(define (list->num list)
  (fold-left (lambda (value digit)
                     (+ (* value 10) digit))
             0
             list))

(list->num '(1 2 3 4))
;Value: 1234


This sounds like a homework question...

Think about powers of ten and what each digit in a number like 1234 actually means.


Here's a solution that uses only tail-recursion

(define (list->num l)
  (cond
   ((null? l) 0)
   ((null? (cdr l)) (car l))
   (else (let ([first (* 10 (car l))][rest (cdr l)])
           (list->num (cons (+ first (car rest)) (cdr rest)))))))


Here are two functions from my Standard Prelude that convert between numbers and lists of digits; both take an optional argument that specifies the radix to be used. They are written in standard R4RS Scheme and should work in any recent Scheme system.

(define (digits n . args)
  (let ((b (if (null? args) 10 (car args))))
    (let loop ((n n) (d '()))
      (if (zero? n) d
          (loop (quotient n b)
                (cons (modulo n b) d))))))

(define (undigits ds . args)
  (let ((b (if (null? args) 10 (car args))))
    (let loop ((ds ds) (n 0))
      (if (null? ds) n
          (loop (cdr ds) (+ (* n b) (car ds)))))))


I write the code as following~~~it works, but the code may be too long~~~

(define (power b e)
  (define (power-product a b e)
    (if (= e 0)
        a
        (power-product (* a b ) b (- e 1))))
  (power-product 1 b e))

(define (length items)
  (if (null? items)
      0
      (+ 1 (length (cdr items)))))

(define (list->num lst)
  (if (null? lst)
      0
      ( + (* (power 10 (- (length lst) 1)) (car lst)) (list->num (cdr lst)))))


Since you've posted your working solution, I'll post this. If you can't use let, you can do similar with a helper function.

(define (list->num l)
  (let loop ((n 0) (l l))
    (if (empty? l)
        n
        (loop (+ (* 10 n) (car l)) (cdr l)))))

A book like "The Little Schemer" is inexpensive, easy and fun to read, and it really gets you thinking in "Scheme mode". It will help you write more concise solutions.

0

精彩评论

暂无评论...
验证码 换一张
取 消