List 从列表中查找元素的位置
我想从列表中找到元素的位置 例如,在给定的列表[[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]] 如果找不到,则应返回空列表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 .. ? 我想用最有效的方法去做。 谢谢。好的,让我们把它分解一下 如果你只对普
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。