我如何浏览一个数字列表,并将其与我正在浏览的另一个列表进行比较



我想输入两个字符串,"你好"以及";嗨"例如,我想同时遍历两个字符串中的每个元素,并逐一比较每个字符。实际程序中的两个字符串长度应为5,如果一个字符等于另一个字符,则返回true,否则返回false。

我脑海中的程序应该在"H"中看到"H";你好"和来自"H"的"H";嗨"并返回true,则我希望它检查"e"中的"e";你好"以及"i"中的"i";嗨"并返回false。我希望它继续这样做,直到没有什么可比的了。我想我可能需要使用递归,但我不确定如何在这个程序中实现它。

我尝试使用最大范围为5的x:xs,所以使用[0..5],但根本不起作用。

我的代码(不工作(:

uncurryingString :: String -> Int -> Char
uncurryingString a b = a !! b
match :: String -> String -> [Int] -> Bool 
match a b (x:xs)
|   uncurryingString a [x+1 | x <- xs]  == uncurryingString b [x+1 | x <- xs]       = True
|   otherwise                                                                       = False 

您认为这种方式太复杂了。

首先,根据经验,您应该永远不要使用!!(无论是直接使用还是通过一些助手使用——uncurryingString实际上与!!本身完全相同(。如果需要直接索引,则列表不是正确的数据结构。但通常情况下,直接索引不是所必需的,它只是其他一些编程语言中通常使用的,这些语言没有模式匹配来更优雅地进行索引。

在您的应用程序中,您正在并行地解构这两个字符串。好吧,你应该用模式匹配来表达这一点:

match (a:as) (b:bs) (x:xs) = ...

现在,您可以简单地直接比较ab,而不需要麻烦任何列表理解或索引运算符。在示例输入"Hello""Hi"中,这里ab都将是'H'

但是您可能不想直接返回True,因为还有字符串的其余部分需要匹配。这就是递归的用武之地

最后,如果不是所有的输入列表都是非空的,则需要使用to子句。试着自己弄清楚。

您可能根本不需要额外的[Int]参数(x:xs)。它可能有一个深度限制参数是有意义的,但这可能只是一个Int。然后你会做一些类似的事情

match :: Eq a => [a] -> [a] -> Int -> Bool
match _ _ 0 = True    -- lists are equal up to the specified max depth
match (a:as) (b:bs) n = ...
...

在Haskell中使用列表理解通常是计算事物的好方法,但在这种特殊情况下不是。

我可以试试这个代码:

[a==b | a <- "Hello", b <- "Hi"]

这是干什么的?你可能认为这会返回True,因为"H"字母匹配——或者你可能认为它会返回False,因为其他字母不匹配。事实上,它同时做到了这两件事——实际上,它正在运行多个嵌套循环。

[True,False,False,False,False,False,False,False,False,False]

因此,当您想要嵌套循环或只处理一个数据集时,需要使用列表理解。在这里,我们只需要一个并行处理这两个单词的循环。因此它必须是递归的。

最新更新