将列表的每个元素与Scheme编程中的另一个列表的每个元素相乘

时间:2011-11-27 21:20:04

标签: list recursion scheme racket multiplication

我正在尝试在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函数,但这似乎不像我想要的那样工作。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

我们首先定义两个输入列表,我重命名它们,因为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程序,这很简单 - 请查看书籍nested mappings中的SICP部分。

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

答案 1 :(得分:3)

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

方案方言Racket有一个很好的内置形式叫for*/list,它完全可以做到这一点:

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

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

答案 2 :(得分:1)

我无法相信没有人给出最直接的答案: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)))))