英文:
A varaible independent its local scope
问题
I tried to solve the twoSum Problem with primitive tools of car and cdr
给定一个整数数组,返回两个数字的索引,使它们的和等于特定目标。
您可以假设每个输入都只有一个解决方案,并且不能重复使用相同的元素。
例子:
给定 nums = [2, 7, 11, 15],target = 9,
因为 nums[0] + nums[1] = 2 + 7 = 9,返回 [0, 1]。
The idea is to take a x
from nums
, then check if x's complement (target - x) is a member of set nums - x
The key logic is
if ((memberp complement (remove-first x nums))
then (list x complement))
Begin with a helper function try nums
(defun two-sum (nums target)
(try nums))
The main function:
(defun try (nums)
(let ((x (car nums))
(complement (- target x)))
(cond
((null x) '())
((memberp complement (remove-first x nums))
(list x complement))
(t (try (cdr nums)))
)))
Then I realize that nums in ((memberp complement (remove-first x nums))
should stay unchanged and independent from the local scope of let.
How could I get such nums?
memberp
and `remove-first':
(defun remove-first (item sequence)
(filter (lambda (x) (not (= x item)))
sequence))
(defun filter (predicate sequence)
(cond ((null sequence) nil)
((funcall predicate (car sequence))
(cons (car sequence)
(filter predicate
(cdr sequence))))
(t (filter predicate
(cdr sequence)))))
(defun memberp (item x)
(cond ((null x) 'false)
((equal item (car x)) x)
(t (memq item (cdr x)))))
英文:
I tried to solve the twoSum Problem with primitive tools of car and cdr
> Given an array of integers, return indices of the two numbers such
> that they add up to a specific target.
>
> You may assume that each input would have exactly one solution, and
> you may not use the same element twice.
>
> Example:
>
> Given nums = [2, 7, 11, 15], target = 9,
>
> Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
The idea is to take a x
from nums
, then check if x's complement (target -x) is member of set nums-x
The key logic is
if ((memberp complement (remove-first x nums))
then (list x complement))
Begin with a helper function try nums
(defun two-sum (nums target)
(try nums))
The main function:
(defun try (nums)
(let ((x (car nums))
(complement (- target x)))
(cond
((null x) '())
((memberp complement (remove-first x nums))
(list x complement))
(t (try (cdr nums)))
)))
Then I realize that nums in ((memberp complement (remove-first x nums))
should be stay unchanged and independent from the local scope of let.
How could get such a nums?
memberp
and `remove-first'
(defun remove-first (item sequence)
(filter (lambda (x) (not (= x item)))
sequence))
(defun filter (predicate sequence)
(cond ((null sequence) nil)
((funcall predicate (car sequence))
(cons (car sequence)
(filter predicate
(cdr sequence))))
(t (filter predicate
(cdr sequence)))))
(defun memberp(item x)
(cond ((null x) 'false)
((equal item (car x)) x)
(t (memq item (cdr x)))))
答案1
得分: 1
以下是用于计算索引的简单递归函数:
(defun two-sum (list target &optional (pos 0))
(if (null (cdr list))
nil
(let ((p (my-position (- target (car list)) list)))
(if p
(list pos (+ pos p))
(two-sum (cdr list) target (1+ pos))))))
(defun my-position (element list &optional (pos 0))
(cond ((null list) nil)
((eql element (car list)) pos)
(t (my-position element (cdr list) (1+ pos)))))
该函数最初使用列表和目标调用。初始时未传递给函数的参数 pos
会自动分配为0,在后续调用中,它将递增一次,以跟踪列表当前元素的索引。
第一个条件检查列表是否少于两个元素:如果为空(或其 cdr
为空),则结果为 nil
,因为没有可能的解决方案(请注意,在Common Lisp中,(cdr nil)
为 nil
)。
否则,我们计算在列表的其余部分中“补数”(请注意,position
是一个原始函数,所以我称其重写为 my-position
)。如果元素存在,我们返回 pos
和 (+ pos p)
(因为找到的位置是相对于当前位置的),否则(当没有找到元素时,my-position
返回 nil
)我们对列表的其余部分进行递归。
请注意,使用这种方法,无需每次考虑列表的所有元素。
英文:
Here is a simple recursive function to compute the indexes:
(defun two-sum (list target &optional (pos 0))
(if (null (cdr list))
nil
(let ((p (my-position (- target (car list)) list)))
(if p
(list pos (+ pos p))
(two-sum (cdr list) target (1+ pos))))))
(defun my-position (element list &optional (pos 0))
(cond ((null list) nil)
((eql element (car list)) pos)
(t (my-position element (cdr list) (1+ pos)))))
The function is initially called with the list and the target. The parameter pos
, which initially is not passed to the function, is assigned automatically to 0, and in the subsequent calls it will be incremented by one, so that it tracks the index of the current element of the list.
The first condition checks if the list has less than two elements: if it is empty (or its cdr
is empty) the result is nil
since no solution is possibile (note that in Common Lisp (cdr nil)
is nil
).
Otherwise we compute the position of the “complement” of the number in the rest of the list (note that position
is a primitive function, so I called my-position
its rewriting). If the element is present, we return both pos
and (+ pos p)
(since the position found is relative to the current position), otherwise (my-position
returns nil
when no element is found) we recur on the rest of the list.
Note that with this method there is no need to consider every time all the elements of the list.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论