Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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 - Fatal编程技术网

List 从列表中查找元素的位置

List 从列表中查找元素的位置,list,haskell,List,Haskell,我想从列表中找到元素的位置 例如,在给定的列表[[1,2,3]、[4,5,6]、[7,8,9]]中,我想找到8的位置。函数应该返回[[3,2]],即第三行和第二列。 如果列表为[[1,2,8],[4,5,6],[7,8,9]] 然后它应该返回: [[1,3],[3,2]] 如果找不到,则应返回空列表 findPosition :: [[Int]] -> [(Int,Int)] findPostion .. ? 我想用最有效的方法去做。 谢谢。好的,让我们把它分解一下 如果你只对普

我想从列表中找到元素的位置

例如,在给定的列表[[1,2,3]、[4,5,6]、[7,8,9]]中,我想找到8的位置。函数应该返回[[3,2]],即第三行和第二列。 如果列表为[[1,2,8],[4,5,6],[7,8,9]] 然后它应该返回: [[1,3],[3,2]] 如果找不到,则应返回空列表

findPosition :: [[Int]]  ->  [(Int,Int)]
findPostion  ..  ?
我想用最有效的方法去做。
谢谢。

好的,让我们把它分解一下

如果你只对普通的整数列表感兴趣,那么

 findPosition :: [Int] -> [Int]
你如何实现这一点?嗯,呃,你需要为你正在搜索的东西输入信息

 findPosition :: Int -> [Int] -> [Int]
好的,酷。因此,内置的elem函数会告诉您所需的元素是否存在。但我们想要它的位置。那怎么办?可以用每个元素的位置来标记每个元素,如下所示:

 label :: [x] -> [(Int, x)]
 label = zip [0..]
现在,我们可以使用过滤器查找所有项目:

 find :: (Eq x) => x -> [(Int, x)] -> [(Int, x)]
 find x0 = filter (\ (n, x) -> x == x0)
但是我们只需要实际的位置,而不是在这一点上完全相同的X。所以我们可以绘制fst图来得到它

把它全部组装起来

 findPosition :: Int -> [Int] -> [Int]
 findPosition x0 = map fst . filter (\ (n, x) -> x == x0) . zip [0..]
太好了!但是你想要一个整数列表,对吗

我建议您更改需求规范,将每个坐标作为元组而不是列表返回。就是这样,

findPosition 8 [[1,2,8],[4,5,6],[7,8,9]] => [(1, 3), (3, 2)]

这样可能就不那么令人困惑了。希望我已经给了你足够的提示,让你从这里找到答案……

好的,让我们来分析一下

如果你只对普通的整数列表感兴趣,那么

 findPosition :: [Int] -> [Int]
你如何实现这一点?嗯,呃,你需要为你正在搜索的东西输入信息

 findPosition :: Int -> [Int] -> [Int]
好的,酷。因此,内置的elem函数会告诉您所需的元素是否存在。但我们想要它的位置。那怎么办?可以用每个元素的位置来标记每个元素,如下所示:

 label :: [x] -> [(Int, x)]
 label = zip [0..]
现在,我们可以使用过滤器查找所有项目:

 find :: (Eq x) => x -> [(Int, x)] -> [(Int, x)]
 find x0 = filter (\ (n, x) -> x == x0)
但是我们只需要实际的位置,而不是在这一点上完全相同的X。所以我们可以绘制fst图来得到它

把它全部组装起来

 findPosition :: Int -> [Int] -> [Int]
 findPosition x0 = map fst . filter (\ (n, x) -> x == x0) . zip [0..]
太好了!但是你想要一个整数列表,对吗

我建议您更改需求规范,将每个坐标作为元组而不是列表返回。就是这样,

findPosition 8 [[1,2,8],[4,5,6],[7,8,9]] => [(1, 3), (3, 2)]
这样可能就不那么令人困惑了。希望我已经给了你足够的提示,让你能从这里找到答案……

一个可能的解决方案:

import Control.Monad

findPosition :: Eq a => a -> [[a]] -> [(Int,Int)]
findPosition e ll = do
    let annotate = zip [1..]
    (i1,x) <- annotate ll
    (i2,y) <- annotate x
    guard $ y == e
    return (i1,i2)
我们用索引注释列表和子列表中的每个元素,并使用列表的Monad实例搜索所有可能的事件。

可能的解决方案:

import Control.Monad

findPosition :: Eq a => a -> [[a]] -> [(Int,Int)]
findPosition e ll = do
    let annotate = zip [1..]
    (i1,x) <- annotate ll
    (i2,y) <- annotate x
    guard $ y == e
    return (i1,i2)

我们用索引注释列表和子列表中的每个元素,并使用列表的Monad实例来搜索所有可能的引用。

您的类型签名是错误的。应该是

findPosition :: Eq a => a -> [[a]] -> [(Int, Int)]
因为

您需要告诉函数要查找什么值 没有理由将findPosition限制为只搜索整数列表,它需要对内部元素进行比较,以确定是否相等 您的版本将返回一个列表,该列表的长度始终为2:如果内部列表为空或长度为3,则这将是一个bug;我们可以通过使用一对来排除这种错误的可能性 我还希望findPosition结果是Haskell的标准列表函数使用的零基索引,而不是您要求的基于一的索引

因此,我将有例如findPosition 8[[1,2,3],[4,5,6],[7,8,9]=[2,1]

不幸的是,Hoogle不知道Eq a=>a->[[a]]->[Int,Int]类型的函数。但是搜索更简单的签名——一个搜索列表而不是列表列表的类似函数——指向我们。我们可以在findPosition中使用它


哦,我太累了,不能完成这个。希望它能让你深思。

你的打字签名是错误的。应该是

findPosition :: Eq a => a -> [[a]] -> [(Int, Int)]
import Data.List

findPosition  :: Int -> [[Int]] -> [(Int,Int)]
findPosition n xs = fp n xs 0

fp n [] i = []
fp n (x:xs) i = p x ++ fp n xs (i+1)
    where 
      p x = zip (repeat i) (elemIndices n x)
因为

您需要告诉函数要查找什么值 没有理由将findPosition限制为只搜索整数列表,它需要对内部元素进行比较,以确定是否相等 您的版本将返回一个列表,该列表的长度始终为2:如果内部列表为空或长度为3,则这将是一个bug;我们可以通过使用一对来排除这种错误的可能性 我还希望findPosition结果是Haskell的标准列表函数使用的零基索引,而不是您要求的基于一的索引

因此,我将有例如findPosition 8[[1,2,3],[4,5,6],[7,8,9]=[2,1]

不幸的是,Hoogle不知道Eq a=>a->[[a]]->[Int,Int]类型的函数。但是搜索更简单的签名——一个搜索列表而不是列表列表的类似函数——指向我们。我们可以在findPosition中使用它

哦,我太累了,不能完成这个。希望它能让你深思

import Data.List

findPosition  :: Int -> [[Int]] -> [(Int,Int)]
findPosition n xs = fp n xs 0

fp n [] i = []
fp n (x:xs) i = p x ++ fp n xs (i+1)
    where 
      p x = zip (repeat i) (elemIndices n x)
例如:

findPosition 3 [[2,3,4,3],[4,5,2,3],[],[3,2,5,6,3],[2],[3]]
   == [(0,1),(0,3),(1,3),(3,0),(3,4),(5,0)]
如果将函数的类型签名更改为:

findPosition :: (Eq a1, Num a) => a1 -> [[a1]] -> [(a, Int)]
您将有一个更一般的解决方案。例如:

findPosition 'a' ["car","small","caveat","big","","aah!"]
   == [(0,1),(1,2),(2,1),(2,4),(5,0),(5,1)]
例如:

findPosition 3 [[2,3,4,3],[4,5,2,3],[],[3,2,5,6,3],[2],[3]]
   == [(0,1),(0,3),(1,3),(3,0),(3,4),(5,0)]
如果将函数的类型签名更改为:

findPosition :: (Eq a1, Num a) => a1 -> [[a1]] -> [(a, Int)]
你会的 我们有一个更一般的解决方案。例如:

findPosition 'a' ["car","small","caveat","big","","aah!"]
   == [(0,1),(1,2),(2,1),(2,4),(5,0),(5,1)]


你只需要第一次出现吗?例如,当给出[[1,2]、[1,3]]并且您想要1的位置时,应该返回什么?不,我想要所有出现的1。在您的示例中,它应该返回[[1,1],[2,1]]。我编辑了文本返回类型也应该是列表列表。我们还需要更多信息。如果数字根本没有出现,它应该返回什么?到目前为止你试过什么?让我们看看你到目前为止有什么。你只需要第一次出现吗?例如,当给出[[1,2]、[1,3]]并且您想要1的位置时,应该返回什么?不,我想要所有出现的1。在您的示例中,它应该返回[[1,1],[2,1]]。我编辑了文本返回类型也应该是列表列表。我们还需要更多信息。如果数字根本没有出现,它应该返回什么?到目前为止你试过什么?让我们看看你到目前为止都做了些什么。zipWith,而不是zip,因为…?哎哟,你是对的。拉链是不必要的。我将编辑答案。您是否使用示例输入输出进行了尝试?这段代码无法编译。我确实试过了。可能问题是我忽略了导入控件。Monad?它给出了错误:由于使用“print”而导致Show[[[[t0]]]]->[Int,Int]没有实例。可能的修复方法是:在交互式GHCi命令的stmt中为Show[[[t0]]]->[Int,Int]添加实例声明:print itzipWith,而不是zip,因为…?哎哟,你是对的。拉链是不必要的。我将编辑答案。您是否使用示例输入输出进行了尝试?这段代码无法编译。我确实试过了。可能问题是我忽略了导入控件。Monad?它给出了错误:由于使用“print”而导致Show[[[[t0]]]]->[Int,Int]没有实例可能的修复方法:在交互式GHCi命令的stmt中为Show[[[[t0]]]]->[Int,Int]添加实例声明:print itCheck this pls:findPosition::Int->[Int]->[Int]findPosition x0=映射fst。过滤器\n,x->x==x0。zip[0..]该函数只接受一个参数,但定义了两个参数。它不能编译在这种情况下,第二个参数可以省略,因为通过组合函数的结果。本身是一个接受单个参数的函数。另一个例子是'add x y=x+y',它与'add x=+x'或'add x=x+'相同。请检查以下内容:findPosition::Int->[Int]->[Int]findPosition x0=map fst。过滤器\n,x->x==x0。zip[0..]该函数只接受一个参数,但定义了两个参数。它不能编译在这种情况下,第二个参数可以省略,因为通过组合函数的结果。本身是一个接受单个参数的函数。另一个例子是'add x y=x+y',它与'add x=+x'或'add x=x+'相同,也可以是:zipWith,=zip。也可以是:zipWith,=zip。