我正在创建一个手动添加大数字的功能(没有库功能),并且我在捕获要显示的结果时遇到一些麻烦。我只是显示回来#()。以下是它应该如何运作的一些背景:如果我通过(big-add1'(999)'(456)0),我应该返回'(455 1)。如果我通过(big-add1'(999 234 681)'(456)0)我应该返回'(455 235 681)。但到目前为止,除了空列表之外,我还没有成功显示任何内容。这是我现在的代码:
(define (big-add1 x y co)
(cond
;; If both lists are empty, the return value is either 0 or the carryover value.
[(and (= 0 (length x)) (= 0 (length y)))
(if (= co 0) '() (list co))]
[(= 0 (length x)) (big-add1 (list co) y 0)]
[(= 0 (length y)) (big-add1 x (list co) 0)]
[else
(cond(< (length x) (length y)) (big-add1 y x 0)) ;reverse the order of parameters
(append (list(+ (modulo (car x) 10) (modulo (car x) 10) co))) ;trying to construct a result
(if(>(+ (modulo (car x) 10) (modulo (car x) 10) co) 9)
(letrec ([co 1]) co) ;if addition produces a double digit number set carryover value
(letrec ([co 0]) co));if addition produces a single digit number
(if(or(> (car x) 10) (> (car y) 10)) ;we got down to single digits
(big-add1(append(list(quotient (car x) 10)) (cdr x)) (append(list(quotient (car y) 10)) (cdr y)) co)
(big-add1 (cdr x) (cdr y) co))
]
))
(big-add1 '(999) '(456) 0)
(big-add1 '(999 234 681) '(456) 0)
奖金问题:如果有人对此感到满意,我可以在调试模式中看到,当总和大于10时,co没有变为1.它似乎执行该行,但实际上并没有改变它。任何人都可以澄清发生了什么事吗? 我对此非常陌生,所以如果有人对如何简化它有任何建议,请随时告诉我。我真的很感激。谢谢你的时间。
答案 0 :(得分:3)
首先,代码中存在大量错误。我列出了几个大的:
else
子句cond
表达式是典型的不返回。append
不会更改给定列表的内容。它是;; trying to...
评论部分。不确定你想做什么。letrec
什么都不做。如果要更改边界值,请使用set!
。其次,以下不是错误,只是提示:
append
创建列表。只需使用list
即可。使用cons
构建列表,然后reverse
结果是常用于返回列表的惯用法之一。因此,如果您看到使用append
,请考虑这一点。null?
程序。如果你想用它来检查它,而不是将它的长度与0进行比较。最后,以下是适合您要求的那个。
;; each element must be less than 1000 (define (big-add1 x y co) (let loop ((x x) (y y) (co co) (r '())) (cond ;; If both lists are empty, the return value is either 0 ;; or the carryover value. [(and (null? x) (null? y)) ;; if there's carry then we need to add it (if (zero? co) (reverse r) (reverse (cons co r)))] [(null? x) (loop x (cdr y) 0 (cons (+ co (car y)) r))] [(null? y) (loop (cdr x) y 0 (cons (+ co (car x)) r))] [else (let ((r (+ (car x) (car y) co))) ;; add elements ;; separate result into element+carry ;; NB: it's better not to put magic number. (let-values (((e co) (if (> r 1000) (values (modulo r 1000) 1) (values r 0)))) ;; next (loop (cdr x) (cdr y) co (cons e r))))])))
答案 1 :(得分:2)
你看起来和我在同一个班级,所以我可以帮助你。上面的Takashi Kato已经回答了你关于球拍/方案如何返回结果的问题(只有最后一个表达式会返回结果),但我想我可以详细说明你想要达到的解决方案。
正如您在问题中描述的那样,big-add函数有两个参数,基本上是一个&#34; chunks&#34;代表一个例如列表'(999 456)
被处理为类似于456,999的数字。每个&#34; chunk&#34;在给定列表中,最大范围只能是0到999(假设我们只是在这里添加正数)。
虽然加藤先生的解决方案可行,但奥斯汀博士(如果我们有相同的教授)会更喜欢你以递归的方式完成这个问题并以与传递的参数相同的格式返回答案in(&#34; chunks&#34;的列表)。提供的清单无需撤销即可。
这是一种思考方式:
append
或cons
每个块的总和,以创建一个返回结果的列表。该算法看起来像这样:
car x
,car y
和co
加在一起来计算块总和:(+ (car x) (car y) co)
。您可以使用let
将此值存储到ID中。我打电话给我chunk-sum
,但你可以把它叫做任何让你更容易理解的东西。在let
的正文中,您必须定义如何处理chunk-sum
以及如何开始创建您返回的列表。chunk-sum
等于或大于1000或MAX_BLOCK_VALUE
(如果您已定义该ID,则它们是等效的),则会有遗留值,因此您需要使用cond
或if
。append
或cons
创建列表。我发现cons
更适合此解决方案,因为cons
可以将数字元素作为其第一个参数,其中append
仅采用列表(因此要求您在list
上使用chunk-sum
{1}})。在此步骤中,您必须递归调用函数big-add1
以不断将元素追加到列表中。如果不完全相同,递归调用的代码看起来与(big-add1 (cdr x) (cdr y) 0)
类似。以下是您尝试完成的代码:
#lang racket
(define MAX_BLOCK_VALUE 1000)
;; Addition of two big-nums
(define (big-add x y)
(big-add1 x y 0)
)
(define (big-add1 x y co)
(cond
;; If both lists are empty, the return value is either 0 or the carryover value. This is our base case
[(and (= 0 (length x)) (= 0 (length y)))
(if (= co 0) '() (list co))]
[(= 0 (length x)) (big-add1 (list co) y 0)]
[(= 0 (length y)) (big-add1 x (list co) 0)]
[else
#| code is here |#
(let ((chunk-sum (+ (car x) (car y) co)))
(if (>= chunk-sum MAX_BLOCK_VALUE)
;; use cons/append and call recursive step for if we have carryover
(error "foo")
;; use cons/append and call recursive step for if we don't have carryover
(error "bar")
)
)
]
))
希望这有帮助。
答案 2 :(得分:0)
我能够通过大量简化算法来解决这个问题。这就是我最终得到的结果:
(define (big-add1 x y co)
(cond
;; If both lists are empty, the return value is either 0 or the carryover value.
[(and (= 0 (length x)) (= 0 (length y)))
(if (= co 0) '() (list co))]
[(= 0 (length x)) (big-add1 (list co) y 0)]
[(= 0 (length y)) (big-add1 x (list co) 0)]
[else
(cons(modulo (+ (car x) (car y) co) 1000)
(if(>(+ (car x) (car y) co) 1000)
(big-add1 (cdr x) (cdr y) 1)
(big-add1 (cdr x) (cdr y) 0))
)
]
))