【问题标题】:Multiplying each element of a list with each element of another list in Scheme programmingScheme编程中将列表的每个元素与另一个列表的每个元素相乘
【发布时间】:2011-11-27 21:20:04
【问题描述】:

我正在尝试在 Scheme 中执行以下操作:

List<int> list = new List<int>();
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list1.Add(2);
list1.Add(4);
list1.Add(6);
list1.Add(8);

for (int i = 0; i < list.Count; i++)
{
    for (int p = 0; p < list1.Count; p++)
    {
         list2.Add(list[i] * list1[p]);
    }
}

如上面的代码所示,我试图将第一个列表中的每个元素与第二个列表中的每个元素相乘。所以 1*2, 1*4, 1*6, 1*8,然后去下一个元素,2*2,2*4..等等。

我无法在 Scheme 中实现这一点。我尝试使用 map 函数,但这似乎并没有按照我想要的方式工作。有什么想法吗?

【问题讨论】:

  • 您是如何使用 map 进行尝试的,但它怎么没有像您想要的那样工作?如果您唯一的问题是结果在嵌套列表中,您可以在之后将其展平。

标签: list recursion scheme racket multiplication


【解决方案1】:

我们从定义两个输入列表开始,我重命名了它们,因为list 是Scheme 中的内置过程,覆盖它不是一个好主意):

(define l '(1 2 3 4))
(define l1 '(2 4 6 8))

我假设您希望您的结果列表是“扁平的” - 例如,它不包含元素列表,仅包含元素(如果您可以在 l2 中包含列表列表,只需删除下面的扁平化调用)。为此,我们需要定义flatten 过程:

(define (atom? x)
  (and (not (pair? x)) (not (null? x))))

(define (flatten lst)
  (cond ((null? lst) empty)
        ((atom? lst) (list lst))
        (else (append (flatten (car lst))
                      (flatten (cdr lst))))))

最后,手头的问题。一旦您了解了如何嵌套两个 map 过程,这很简单 - 请查看本书 SICP 中的 nested mappings 部分。

(define l2
  (flatten
   (map (lambda (i)
          (map (lambda (j)
                 (* i j))
               l1))
        l)))

此时,l2 包含预期的答案:

(2 4 6 8 4 8 12 16 6 12 18 24 8 16 24 32)

【讨论】:

    【解决方案2】:

    Óscar 已经对这个问题给出了非常完整的答案,但我想补充两点:

    Scheme 方言 Racket 有一个很好的内置形式,称为 for*/list,它正是做这样的事情:

    (for*/list ([i '(1 2 3 4)]
                [j '(2 4 6 8)])
      (* i j))
    

    另外,您可以在嵌套映射解决方案中使用您自己的或库的flatten 函数,而不是使用SRFI-1 中的append-map 替换外部map。当然,还有很多其他方法;-)

    【讨论】:

      【解决方案3】:

      我不敢相信没有人给出最直接的答案:map 的嵌套使用:

      (append-map (lambda (x)
                    (map (lambda (y) (* x y))
                         (list 2 4 8 6)))
                  (list 1 2 3 4))
      

      append-mapmap 的一个简单变体,它假定映射函数返回一个列表,因此它连接所有结果列表。这是最重要的 Scheme 系统中的一个库函数(位于 the SRFI-1 library 中),但这里有一个简单的、不完整的定义(一个完整的定义会处理多个参数列表):

      (define (append-map f xs)
        (concat (map f xs)))
      
      ;;;
      ;;; Turns a list of lists into a list by appending all the top-level sublists.
      ;;; This is also a common library function.
      ;;;
      (define (concat lists)
        (if (null? lists)
            '()
            (append (car lists)
                    (concat (cdr lists)))))
      

      【讨论】:

        猜你喜欢
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多