Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 合并两个元组列表_List_Haskell_Recursion_Merge - Fatal编程技术网

List 合并两个元组列表

List 合并两个元组列表,list,haskell,recursion,merge,List,Haskell,Recursion,Merge,我需要创建一个递归函数,将两个元组列表合并在一起,并从一个已知的元组开始。该函数接收三个参数: 两个元组列表 元组 我试过这个: mergePoints l1 l2 o=o++[f |(a,b)根据您的示例 ghci> mergePoints [(1, 3), (1, 4), (5, 5)] [(1, 1), (4, 4)] (0, 0) [ (0.0, 0.0), (1.0, 1.0),

我需要创建一个递归函数,将两个元组列表合并在一起,并从一个已知的元组开始。该函数接收三个参数:

  • 两个元组列表
  • 元组
我试过这个:


mergePoints l1 l2 o=o++[f |(a,b)根据您的示例

ghci> mergePoints [(1, 3), (1, 4), (5, 5)] [(1, 1), (4, 4)] 
      (0, 0)
[    (0.0, 0.0),                          (1.0, 1.0), 
               (1.0, 3.0), (1.0, 4.0),            (4.0, 4.0), 
                                  (5.0, 5.0)]
这两个列表中的每一个都以自己的速度使用,因此
zip
不适合这里,因为它以相同的速度使用参数列表

最简单的编码方法是使用带有模式匹配的直接递归定义,该定义将比较两个头部元素,并根据比较结果使用其中一个或另一个

也许您还需要将它们与提供的第三点进行比较,以防它不是最小的


那么,关于你的代码

从示例输入和输出判断,这些点应该是按顺序出现的。我们可以在元组定义字典顺序时比较它们。您已经在这样做了。通过一个小的语法修复,您的代码是:

mergePoints1 l1 l2 o  =  o ++ [f | (a, b) <- zip l1 l2, 
                                   let f if a < b then f = [a, b] 
                                                  else f = [b, a]]
(对“结果”使用
r
,而不是
f
)。最后一个错误是
++
连接了两个列表,但
o
不是一个列表。因此它必须是

mergePoints4 l1 l2 o  =  [o] ++ merge1 l1 l2

merge1 l1 l2  =  [r | (a, b) <- zip l1 l2, 
                      r <- if a < b then [a, b] else [b, a]]
或者我们可以使用

merge3 l1 l2  =  l1 ++ l2
  where
  []     ++ l2      =  l2
  l1     ++ []      =  l1
  (x:t1) ++ (y:t2)  =  x : y : (t1 ++ t2)   -- or:
               --   =  x : ((y:t2) ++ t1)
当然,一个接一个地取出元素可能会扰乱它们的顺序。您试图用
merge1
纠正这一点的尝试可以重新写入

merge1b l1 l2  =  l1 ++ l2
  where
  []     ++ l2  =  l2
  l1     ++ []  =  l1
  (x:t1) ++ (y:t2)  =  if  x < y  then  x : y : (t1 ++ t2)
                       else             y : x : (t1 ++ t2)
merge1b l1=l1++l2
哪里
[]++l2=l2
l1++[]=l1
(x:t1)+(y:t2)=如果x
但它仍然可以扰乱顺序。我们假设我们的两个输入是有序的,增加列表,其中每个元素都比列表中紧随其后的元素小。因此,我们只需要使用这些知识,小心地拉动其中一个元素:

merge4 l1 l2  =  l1 ++ l2
  where
  []     ++ l2      =  l2
  l1     ++ []      =  l1
  (x:t1) ++ (y:t2)  =  if   x < y  then  x : (_ ++ (y:t2))
                       else              _ : _
merge4 l1=l1++l2
哪里
[]++l2=l2
l1++[]=l1
(x:t1)+(y:t2)=如果x
您需要用实际代码替换
来完成此定义


附加问题:Haskell中的
merge
的通常定义更喜欢它的“左”参数而不是“右”参数,以防两个元素相等。为此,对代码进行一个字符的编辑。

我理解。新的问题是,我不确定如何进行这种递归。下面是一个示例:
foo x | x>10=[]|否则=x:foo(x+1)
。这里是另一个:
bar[]=[];bar(x:xs)| x>10=[]|否则=x:bar xs
。我最后得出结论:
mergePoints[][]o=[];mergePoints(x:xs)(y:ys)o | xy=p++[y]+[x]++mergePoints xs ys;其中p=o:[]
,我知道我的错误在哪里,我只是不知道如何处理它。我让它工作,另一种方式。我首先想做的是你在mergePoints2中所做的,但我在let子句中遇到了错误,所以你所做的帮助我理解了我的错误,现在我知道了如何处理它。其余的一切对我理解bi来说都是一个很好的帮助更多Haskell及其工作原理。非常感谢,这是一个非常好的帮助。如果它“从已知的元组开始”,然后简单地
mergePoints l1 l2 o=o:mergePoints S2 l1 l2
,不是吗?为什么是dv?OP陈述了问题,展示了对解决方案、样本输入和所需输出进行编码的尝试……我认为这是一个几乎完美的问题。事实上,我应该马上回答它。如果它足够好回答,就足够好回答你普沃特。
merge2 l1 l2  =  l1 ++ l2
  where                     -- the definition of the built-in `++`:
  []     ++ l2  =  l2
  l1     ++ []  =  l1
  (x:t1) ++ l2  =  x : (t1 ++ l2)
merge3 l1 l2  =  l1 ++ l2
  where
  []     ++ l2      =  l2
  l1     ++ []      =  l1
  (x:t1) ++ (y:t2)  =  x : y : (t1 ++ t2)   -- or:
               --   =  x : ((y:t2) ++ t1)
merge1b l1 l2  =  l1 ++ l2
  where
  []     ++ l2  =  l2
  l1     ++ []  =  l1
  (x:t1) ++ (y:t2)  =  if  x < y  then  x : y : (t1 ++ t2)
                       else             y : x : (t1 ++ t2)
merge4 l1 l2  =  l1 ++ l2
  where
  []     ++ l2      =  l2
  l1     ++ []      =  l1
  (x:t1) ++ (y:t2)  =  if   x < y  then  x : (_ ++ (y:t2))
                       else              _ : _