Recursion 通过递归函数(Ocaml)交错两个列表

Recursion 通过递归函数(Ocaml)交错两个列表,recursion,ocaml,Recursion,Ocaml,我在这里面临着相当大的挑战,希望您能提供一些帮助 我已经尝试了很多,但是没有成功 问题是: 两张名单 List1 : [a1; a2; ...; an] List2 : [b1; b2; ...; bn] 返回两个列表中可能的所有交织列表的函数是什么,该列表与每个列表中的顺序有关 例如: myFunction [1; 2] ['a'; 'b'; 'c'] = [ [1; 2; 'a'; 'b'; 'c']; [1; 'a'; 2; 'b'; 'c']; [1; '

我在这里面临着相当大的挑战,希望您能提供一些帮助

我已经尝试了很多,但是没有成功

问题是:

两张名单

List1 : [a1; a2; ...; an]
List2 : [b1; b2; ...; bn]
返回两个列表中可能的所有交织列表的函数是什么,该列表与每个列表中的顺序有关

例如:

myFunction [1; 2] ['a'; 'b'; 'c'] = [ 
    [1; 2; 'a'; 'b'; 'c']; 
    [1; 'a'; 2; 'b'; 'c']; 
    [1; 'a'; 'b'; 2; 'c']; 
    [1; 'a'; 'b'; 'c'; 2]; 
    ['a'; 1; 2; 'b'; 'c']; 
    ['a'; 1; 'b'; 2; 'c']; 
    ['a'; 1; 'b'; 'c'; 2]; 
    ['a'; 'b'; 1; 2; 'c']; 
    ['a'; 'b'; 1; 'c'; 2]; 
    ['a'; 'b'; 'c'; 1; 2] 
]
对于那些已经注意到的人来说,它基本上是考虑两个并发程序,并且在启动这两个程序时所有可能的执行(1总是在2之前,a总是在b之前和c之前,否则,所有的交织都是可能的)

我希望我是清楚的,你能帮助我


多谢各位

因为这是家庭作业,这里有一些提示:

1) 。该函数将获取两个相同类型的列表
'a list
,并返回一个
'a list

val interleave: 'a list -> 'a list -> 'a list list
2) 。如果一个列表为空,则结果是由另一个列表组成的单例列表。
3). 假设您希望在两个非空列表
x::xs
y::ys
上执行
interleave
。有两种交织。第一种是
x
作为结果列表的头部,您可以将
x
放在从
交错xs(y::ys)
返回的任何列表的开头。第二类具有
y
作为新的头,您可以将
y
预先添加到从
交织(x::xs)ys
获得的任何列表中

有了这些提示,我认为您可以创建一个带有一些模式匹配案例的递归函数来解决这个问题

(* Each interleaving of non-empty lists lst1 = [x1; x2; ...; xm]
   and lst2 = [y1; y2; ...; yn] begins either with x1 or with y1.
   Thus we may get all the interleavings as follows:

   1. Compute all interleavings of [x2; ...; xm] and [y1; ...; yn]
      and prepend x1 to each one of them.

   2. Compute all interleavings of [x1; ...; xm] and [y2; ...; yn]
      and prepend y1 to each one of them.

   Append the lists obtained in steps 1 and 2 to get all possible
   interleavings. The border cases is when either one of the lists
   is empty, but that is easy to figure out. Here is the corresponding
   code.
*)

let rec interleave lst1 lst2 =
  match lst1, lst2 with
    | [], ys -> [ys]
    | xs, [] -> [xs]
    | x :: xs, y :: ys ->
        (List.map (fun zs -> x :: zs) (interleave xs (y::ys))) @
        (List.map (fun zs -> y :: zs) (interleave (x::xs) ys))
测试用例:

# interleave [1;2] [100;200;300] ;;
- : int list list =
[[1; 2; 100; 200; 300]; [1; 100; 2; 200; 300]; [1; 100; 200; 2; 300];
[1; 100; 200; 300; 2]; [100; 1; 2; 200; 300]; [100; 1; 200; 2; 300];
[100; 1; 200; 300; 2]; [100; 200; 1; 2; 300]; [100; 200; 1; 300; 2];
[100; 200; 300; 1; 2]]
注意:在Ocaml中,列表是单态的,因此我们不能像问题中建议的那样交错字符串和整数。或者换一种方式,因为我们必须使用
求和类型。

这是家庭作业吗?第二个问题:
myFunction[1][1]
你想要什么答案?还有一个观察:您的示例是无效的OCaml——您不能有混合字符和整数的列表。(但想法很清楚。)这只是一个大得多的家庭作业的一部分。而myFunction[1][1]将返回[[1;1];[1;1]],这两个列表都有可能返回。对于我的例子,我只是想让它更清楚,因为我认为两个数字列表会混淆。希望没问题。谢谢你,太好了!既然你允许复制,我想说pad的提示看起来很棒。谢谢杰弗里和pad。你们的提示很有帮助,我正在考虑它们(以及你们在一篇关于在F#中合并列表的旧帖子中给出的提示)。“对称地,你可以在interleave(x::xs)ys列表中的任何列表中插入y”,因为我认为这是我丢失的拼图。感谢您了解这是如何工作的(顺便说一句),帮助我认识到如果两个列表都是非空的,那么只有两种交错。一种是从一个列表的开头开始的。另一种是从另一个列表的头开始的。这足以导出pad的分析(通过递归)。