【问题标题】:Combining two list in lisp to output certain item在 lisp 中组合两个列表以输出某些项目
【发布时间】:2015-04-10 14:00:56
【问题描述】:

我目前已经解决了背包问题,并且有两个如下列表

清单1((帽子10 5)(衣服10 10)(帐篷40 70))

列表 2 (((1 1 1).0) ((1 0 1) .23) ((1 0 0) .45) ((0 0 0) .0))

列表 2 表示是否使用项目。((1 1 1) .0) 表示所有项目均已使用,0 表示它的有用程度。我的最终输出是二进制的,但我想知道如何创建一个函数来获取两个列表并显示实际项目,如下例所示

而不是打印 ((1 0 1) .23) 打印((帽子帐篷)。23))

【问题讨论】:

    标签: list lisp common-lisp


    【解决方案1】:

    如果我理解正确,听起来您有一个本质上是掩码的列表,以及相同长度的项目列表,并且对于掩码的每个元素,您想从相应的项目中收集一些东西在项目列表中。我不确定这种函数的最佳名称是什么,但这里有一个实现,将其称为 decode

    (defun decode (mask items &key (key 'identity) (test 'identity))
      (loop
         for bit in mask
         for item in items
         when (funcall test bit)
         collect (funcall key item)))
    

    CL-USER> (decode '(nil t nil nil t) '(a b c d e))
    ; (B E)
    CL-USER> (decode '(nil t nil nil t) '(a b c d e) :key 'symbol-name)
    ; ("B" "E")
    CL-USER> (decode '(nil t nil nil t) '(a b c d e) :test 'null)
    ; (A C D)
    

    将其应用于您的用例并不难;测试的是掩码元素是否非零,关键函数是first,因为你要的是item的名字:

    (defparameter *items*
      '((hat 10 5) (clothes 10 10) (tent 40 70)))
    
    (defparameter *solutions*
      '(((1 1 1) . 0) ((1 0 1) . 23) ((1 0 0) . 45) ((0 0 0) . 0)))
    
    (decode '(1 0 1) *items*
            :key 'first
            :test (complement #'zerop))
    ;;=> (hat tent)
    
    (mapcar #'(lambda (solution)
                (cons (decode (car solution)
                              *items*
                              :key 'first
                              :test (complement #'zerop))
                      (cdr solution)))
            *solutions*)
    ;;=> (((HAT CLOTHES TENT) . 0) ((HAT TENT) . 23) ((HAT) . 45) (NIL . 0))
    

    【讨论】:

      猜你喜欢
      • 2015-03-31
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2020-06-06
      • 1970-01-01
      相关资源
      最近更新 更多