【发布时间】:2021-03-07 08:13:09
【问题描述】:
我编写了以下 C 代码来递归解决给定问题,即接收一个非空整数列表和一个目标值,并返回最接近的正值而不超过目标。例如(3 4) 与目标 2 应该返回 1。唯一的组合是 -3 + 4 = 1。:
int closest(int arr[], int target, int i, int n)
{
if (i == n)
return 0;
int sum1 = arr[i] + closest(arr, target - arr[i], i + 1, n);
int sum2 = -1 * arr[i] + closest(arr, target + arr[i], i + 1, n);
if (abs(sum1 - target) < abs(sum2 - target))
{
return sum1;
}
else
{
return sum2;
}
}
不幸的是,这个问题是用 Racket 编写的,限制使用 car + cdr 而不是使用 let 为 sum1/sum2 创建变量,我遇到了很大的困难。
到目前为止:
(define closest (lambda (l target i n)
(cond
((= i n)0)
)
)
)
我的问题是:如何将 arr[i] 和指针转换为 car/cdr 逻辑?我隐约明白它控制两个值,但迭代似乎把我的大脑一分为二。
【问题讨论】:
-
大概 C 函数最初是用
i作为 0 调用的......每次再次调用它时它都会增加一个,直到它等于 n......这可以直接转换为链接列表和汽车/cdr。 -
从这个骨架开始:
(define (closest lst target) (if (null? lst) 0 (the rest of the code here))). -
请注意,您可以将
(let ((x v)) e)翻译成((lambda (x) e) v),它以“明显”的方式推广到多个定义。如果您首先重写您的 C 函数以使用指针算术(删除i)并想象有一种方法可以从指针确定您已到达数组的末尾,则迭代更容易掌握。 -
"没有越过目标"你的 C 代码不这样做。你用
abs来比较。 -
(define closest (lambda (arr targ) (if (null? lst) 0 ((lambda (sum1 sum2) .... ) (+ (closest (cdr arr) (- targ (car arr))) (car arr)) (- .... ) ))))。这反映了 C 代码,因此,找到低于或高于目标的最接近的值。
标签: c recursion scheme racket code-translation