2013-10-25 1 views
0

내가하려는 것은 두 개의 목록을 취하고 각 목록처럼 정수를 더하는 것입니다.숫자 목록을 사용하는 임의 정밀도 추가

(define (reverse lst) 
(if (null? lst) 
    '() 
    (append (reverse (cdr lst)) 
     (list (car lst))))) 

(define (apa-add l1 l2) 
    (define (apa-add-help l1 l2) 
    (cond ((and (null? l1) (null? l2)) '()) 
     ((null? l1) (list (+ (apa-add-help '() (cdr l2))))) 
     ((null? l2) (list (+ (apa-add-help (cdr l1) '())))) 

     ((>= (+ (car l1) (car l2)) 10) 
     (append (apa-add-help (cdr l1) (cdr l2))    
       (list (quotient (+ (car l1) (car l2)) 10)) 
       (list (modulo (+ (car l1) (car l2)) 10)))) ;this is a problem 

     (else (append (apa-add-help (cdr l1) (cdr l2)) 
        (list (+ (car l1) (car l2))))))) 

(apa-add-help (reverse l1) (reverse l2))) 

(apa-add '(4 7 9) '(7 8 4)) 
>'(1 1 1 5 1 3) 

나는 문제가 내 재귀 주위에 회귀 것을 알고, 나는 그러나 내 모듈로 값을 추가하는 방법을 이해할 수없는 것, 쉽게 프로세스를 허용하는 목록의 순서를 반전 (값을 통해 수행) 목록의 다음 객체로 이동합니다. 어떻게해야합니까?

답변

1

reverse은 이미 Racket에 정의되어 있으므로 다시 정의 할 필요가 없습니다.

(define (apa-add l1 l2) 

    (define (car0 lst) (if (empty? lst) 0 (car lst))) 
    (define (cdr0 lst) (if (empty? lst) empty (cdr lst))) 

    (let loop ((l1 (reverse l1)) (l2 (reverse l2)) (carry 0) (res '())) 
    (if (and (null? l1) (null? l2) (= 0 carry)) 
     res 
     (let* ((d1 (car0 l1)) 
       (d2 (car0 l2)) 
       (ad (+ d1 d2 carry)) 
       (dn (modulo ad 10))) 
      (loop (cdr0 l1) (cdr0 l2) (quotient (- ad dn) 10) (cons dn res)))))) 

같은

-> (apa-add '(4 7 9) '(7 8 4)) 
'(1 2 6 3) 
-> (+ 479 784) 
1263 

car0cdr0 나 처리를 계속하는 데 도움이 기능은 다음과 같습니다

나는 명확하게 (나에게, 적어도) 인 버전에 대한 코드를 다시 작성했다 빈 목록을 0의 목록으로 만듭니다.

필자가 수동으로하는 것처럼 iteration에서 iteration으로 값을 전달하는 데 사용되는 carry라는 새로운 변수가 도입되었습니다.

EDIT 1

named let 다음 코드에 해당 :

(define (apa-add l1 l2) 

    (define (car0 lst) (if (empty? lst) 0 (car lst))) 
    (define (cdr0 lst) (if (empty? lst) empty (cdr lst))) 

    (define (apa-add-helper l1 l2 carry res) 
    (if (and (null? l1) (null? l2) (= 0 carry)) 
     res 
     (let* ((d1 (car0 l1)) 
       (d2 (car0 l2)) 
       (ad (+ d1 d2 carry)) 
       (dn (modulo ad 10))) 
      (apa-add-helper (cdr0 l1) (cdr0 l2) (quotient (- ad dn) 10) (cons dn res))))) 

    (apa-add-helper (reverse l1) (reverse l2) 0 '())) 

편집 2

비 꼬리 재귀 버전이 될 것

(define (apa-add l1 l2) 

    (define (car0 lst) (if (empty? lst) 0 (car lst))) 
    (define (cdr0 lst) (if (empty? lst) empty (cdr lst)))  

    (define (apa-add-helper l1 l2 carry) 
    (if (and (null? l1) (null? l2) (= 0 carry)) 
     '() 
     (let* ((d1 (car0 l1)) 
       (d2 (car0 l2)) 
       (ad (+ d1 d2 carry)) 
       (dn (modulo ad 10))) 
      (cons dn (apa-add-helper (cdr0 l1) (cdr0 l2) (quotient (- ad dn) 10)))))) 

    (reverse (apa-add-helper (reverse l1) (reverse l2) 0))) 
+0

당신이 코드에서 무슨 일이 일어나고 있는지 다소 혼란 스럽습니다. 정확히 루프 기능은 무엇입니까? 그리고 0을 나르는가? – LostSchemer

+0

이름이 지정된 let_에 대한 편집을 참조하십시오. Carry는 10을 초과하는 값이며, 다음 더하기로 10을 나눈 값으로 이월됩니다. – uselpa

+0

좋아, 이제 한 번 더 보게됩니다. – LostSchemer