如何使用列表理解和递归检测 Haskell 中两个相邻的相同字符?
How to detect two adjacent identical characters in Haskell using list comprehension and recursion?
我正在尝试编写一个函数 detadj :: String -> Bool
,它接受一个字符串,如果 returns 为真
该字符串包含两个相同的相邻字符。例如:
detadj "" == False
detadj "s" == False
detadj "ss" == True
detadj "Misisipi" == False
detadj "Mississippi" == True
detadj "single-dash" == False
detadj "double--dash" == True
我有两个版本的函数,第一个在列表理解中,在很多情况下都是错误的,但最普遍的是 detadjlc ["ss"]
时,由于使用 (x:y:xs)
位:
detadjlc :: String -> Bool
detadjlc [] = False
detadjlc [x] = False
detadjlc (x:y:xs) = head[ x == y && isAlpha x == isAlpha y | (x,y) <- zip (x:y:xs) xs ]
和递归(当输入类似于 detadjr [" ee"]
产生 False
而不是 True
时,这不起作用):
detadjr :: String -> Bool
detadjr [] = False
detadjr [x] = False
detadjr (x:y:xs) | x == y = True
| otherwise = d xs
有哪些方法可以解决这些问题?
你的递归函数很好,除了一个小细节:你忘记将 y
放回递归调用的列表中。 (我假设 d
是 detadjr
的拼写错误。)仅仅因为 x
和 y
不同并不意味着 y
和 [= 的第一个字符17=] 可能不一样。
detadjr :: String -> Bool
detadjr (x:y:xs) = (x == y) || detadjr (y:xs)
detadjr _ = False
(如果您首先检查 2 个或更多字符的字符串,那么单例和空列表可以折叠成一个基本案例。)
以下是使用列表理解的迭代解决方案。我们创建一个包含输入列表相邻元素的元组列表。然后我们比较元组中的那些元素。
detadjlc :: String -> Bool
detadjlc xs = or [x == y | (x, y) <- zip xs (tail xs)]
递归解决方案最好按照@chepner 已发布的方式完成。
我正在尝试编写一个函数 detadj :: String -> Bool
,它接受一个字符串,如果 returns 为真
该字符串包含两个相同的相邻字符。例如:
detadj "" == False
detadj "s" == False
detadj "ss" == True
detadj "Misisipi" == False
detadj "Mississippi" == True
detadj "single-dash" == False
detadj "double--dash" == True
我有两个版本的函数,第一个在列表理解中,在很多情况下都是错误的,但最普遍的是 detadjlc ["ss"]
时,由于使用 (x:y:xs)
位:
detadjlc :: String -> Bool
detadjlc [] = False
detadjlc [x] = False
detadjlc (x:y:xs) = head[ x == y && isAlpha x == isAlpha y | (x,y) <- zip (x:y:xs) xs ]
和递归(当输入类似于 detadjr [" ee"]
产生 False
而不是 True
时,这不起作用):
detadjr :: String -> Bool
detadjr [] = False
detadjr [x] = False
detadjr (x:y:xs) | x == y = True
| otherwise = d xs
有哪些方法可以解决这些问题?
你的递归函数很好,除了一个小细节:你忘记将 y
放回递归调用的列表中。 (我假设 d
是 detadjr
的拼写错误。)仅仅因为 x
和 y
不同并不意味着 y
和 [= 的第一个字符17=] 可能不一样。
detadjr :: String -> Bool
detadjr (x:y:xs) = (x == y) || detadjr (y:xs)
detadjr _ = False
(如果您首先检查 2 个或更多字符的字符串,那么单例和空列表可以折叠成一个基本案例。)
以下是使用列表理解的迭代解决方案。我们创建一个包含输入列表相邻元素的元组列表。然后我们比较元组中的那些元素。
detadjlc :: String -> Bool
detadjlc xs = or [x == y | (x, y) <- zip xs (tail xs)]
递归解决方案最好按照@chepner 已发布的方式完成。