【问题标题】:A varaible independent its local scope一个独立于其局部范围的变量
【发布时间】:2020-01-06 14:50:09
【问题描述】:

我尝试用car和cdr的原始工具解决twoSum问题

给定一个整数数组,返回两个数字的索引,例如 它们加起来就是一个特定的目标。

您可以假设每个输入都只有一个解,并且 您不能两次使用相同的元素。

例子:

给定 nums = [2, 7, 11, 15],目标 = 9,

因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]。

想法是从nums 中获取x,然后检查x 的补码(目标-x)是否是集合nums-x 的成员

关键逻辑是

if ((memberp complement (remove-first x nums)) 
then  (list x complement))

从辅助函数try nums开始

(defun two-sum (nums target)
 (try nums))

主要功能:

(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)))
     )))

然后我意识到((memberp complement (remove-first x nums)) 中的 nums 应该保持不变并且独立于 let 的本地范围。

怎么会得到这样的数字?

memberp 和 `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)))))

【问题讨论】:

    标签: lisp elisp


    【解决方案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,在后续调用中会加1,以便跟踪列表当前元素的索引。

    第一个条件检查列表是否少于两个元素:如果它是空的(或者它的 cdr 是空的)结果是 nil 因为没有解决方案是可能的(注意在 Common Lisp 中 (cdr nil)nil)。

    否则我们计算列表其余部分中数字的“补码”的位置(注意position 是一个原始函数,所以我将my-position 称为它的重写)。如果元素存在,我们返回pos(+ pos p)(因为找到的位置是相对于当前位置的),否则(my-position 在没有找到元素时返回nil)我们在其余部分重复列表。

    请注意,使用此方法无需每次都考虑列表中的所有元素。

    【讨论】:

      猜你喜欢
      • 2014-03-02
      • 2013-10-14
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 2016-11-13
      • 2013-05-10
      • 2014-07-14
      • 2022-01-12
      相关资源
      最近更新 更多