使用递归混合两个列表中的值 [英] Mix values from two List using recursion
问题描述
我想使用两个列表来混合值:
I want to mix values using two lists:
List1 : [3; 2; 8; 1; 9; 3; 6]
List2: [5; 7; 0]
Output : [3; 5; 2; 7; 8; 0; 1; 9; 3; 6]
我只有长度相同的列表信息,当我与其他人有差异时,该示例又如何呢?
I only found info about list with the same length what about this example when i have diffrent ?
相同长度:
let rec mix =function
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
|([],[]) -> []
| _ -> failwith "mix:param";;
mix ([3;2;8;1;9;3;6], [5; 7; 0]) ;;
推荐答案
最好的分解方法是考虑特定步骤的每种可能情况.您当前有:
The best way to break this down is by considering each possible case for a particular step. You currently have:
-
|(x::xs,y::ys)
在这种情况下,每个列表还剩下至少一个项目 -
|([],[])
这是两个列表都为空的情况 -
_
这种情况下可以处理其他所有情况.
|(x::xs,y::ys)
This is the case where each of the lists has at least one more item left|([],[])
This is the case where both lists are empty_
This case handles everything else.
因此,您缺少的情况是一个列表为空而另一个列表至少还剩一个项目的情况.这些情况是|(x::xs,[])
和|([],y::ys)
.因此,将这两个选项添加到您的match语句中,如下所示:
So the cases you are missing are the cases where one list is empty and the other list has at least one item left. Those cases are |(x::xs,[])
and |([],y::ys)
. So add those two options to your match statement like so:
let rec mix =function
|(x::xs,[]) |([],y::ys) -> failwith "do something here"
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
|([],[]) -> []
| _ -> failwith "mix:param"
您会注意到,您现在收到一条警告,指示最后一种情况将永远不会匹配,因此可以像这样将其删除:
You'll notice that you now get a warning indicating that the last case will never be matched so it can be removed like so:
let rec mix =function
|([],[]) -> []
|(x,[]) |([],x) -> failwith "test"
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
请注意如何将基本情况移动到顶部,以便在(x,[])
或([], x)
之前将其匹配.现在所需要做的就是处理后两种情况的代码.看起来像这样:
Notice how I moved the base case to the top so it gets matched before (x,[])
or ([], x)
. Now all that is needed is code to handle those last two cases. It looks like this:
|(x,[]) |([],x) -> x
,即返回列表中的其余值.
|(x,[]) |([],x) -> x
i.e. return the rest of the values in the list.
所以最终的解决方案是这样的:
So the final solution looks like this:
let rec mix =function
|([],[]) -> []
|(x,[]) |([],x) -> x
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
您还可以进行进一步的偷偷摸摸的优化,因为该基础外壳将被第二个外壳覆盖,因此可以完全删除该基础外壳.即(x,[])
也与([],[])
匹配,并将根据需要返回[]
.剩下的只是:
A further sneaky optimization you could make would be to remove the base case entirely since it will be covered by the second case. I.e (x,[])
also matches ([],[])
and will return []
as desired. This leaves us with just:
let rec mix =function
|(x,[]) |([],x) -> x
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
这篇关于使用递归混合两个列表中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!