忽略非字母数字字符和大小写的回文检查器 Haskell
Palindrome checker that ignores non-alphanumeric characters and case Haskell
需要编写一个程序来检查给定字符串是否为回文,无论大小写是否不同,它都应该可以工作,并且应该忽略非字母数字字符,仅使用 Data.char 中的 ord 和 chr 函数和常规功能,仅此而已。我能够创建常规回文检查器:
reverseStr::String->String
reverStr s | s == [] = []
reverseStr (h:t) = reverseStr t ++ [h]
isPalindrome :: String -> Bool
isPalindrome s = s == reverseStr s
我已经开始研究一个函数来标准化大小写:
normalizeCase::String->String
normalizeCase h | h == [] = []
normalizeCase (h) = if ord h > 64 && ord h < 123
then map (chr $ (ord h + 32)) [h]
else h
但是我得到了这些错误:
• Couldn't match expected type ‘Char -> Char’
with actual type ‘Char’
• In the first argument of ‘map’, namely ‘(chr $ (ord h + 32))’
In the expression: map (chr $ (ord h + 32)) [h]
In the expression:
if ord h > 64 && ord h < 123 then
map (chr $ (ord h + 32)) [h]
else
h
|
6 | then map (chr $ (ord h + 32)) [h] | ^^^^^^^^^^^^^^^^^^
• Couldn't match type ‘Char’ with ‘[Char]’
Expected type: String
Actual type: Char
• In the expression: h
In the expression:
if ord h > 64 && ord h < 123 then
map (chr $ (ord h + 32)) [h]
else
h
In an equation for ‘normalizeCase’:
normalizeCase [h]
= if ord h > 64 && ord h < 123 then
map (chr $ (ord h + 32)) [h]
else
h
|
7 | else h | ^
我对 Haskell 还是很陌生,不知道如何正确实施 ord 或 chr 以便它与此检查器一起工作,所以任何帮助将不胜感激!
在此代码中:
normalizeCase::String->String
normalizeCase h | h == [] = []
normalizeCase (h) = if ord h > 64 && ord h < 123
then map (chr $ (ord h + 32)) [h]
else h
您的第二个模式 (h)
(仅相当于 h
)匹配 任何 列表(只要它尚未与第一个模式匹配, h | h == []
);所以 h
是一个列表,ord h
没有意义,因为 ord
期望 Char
,而不是 [Char]
.
假设 h
是一个字符,那么 chr $ ord h + 32
也是一个字符,但是 map
期望 函数 作为它的第一个参数;这是预期 Char -> Char
但你给了 Char
的错误来源。对于 map
的第二个参数,您传递 [h]
,它是单个元素 h
的列表(在您的代码中也是一个列表,因此您提供 [[Char]]
当你想要 [Char]
).
同时假设 h
是一个字符,您的条件 ord h > 64 && ord h < 123
匹配 uppercase A
和 lowercase 之间的任何字符 z
,包括几个你不想要的字符([]^_`
)。 h
是字符的 列表 这一事实是错误的来源,即 Char
是预期的,但你给出了 [Char]
.
您似乎也在将递归样式与 map
混合使用——在这种情况下,您应该 或者 使用 map
或者 用例定义函数。
下面是您的代码在修复这些错误后的样子。一、使用递归:
normalizeCase :: String -> String
-- Given an empty list, return an empty list.
-- This happens if the original input was empty,
-- or when we reach the end of the recursion.
normalizeCase [] = []
-- Given a non-empty list,
-- test the first character ‘c’.
normalizeCase (c : cs) = if c >= 'A' && c <= 'Z'
-- If it’s uppercase, lowercase it and
-- prepend it to the result of normalizing
-- the remainder of the string ‘cs’.
then chr (ord c + 32) : normalizeCase cs
-- Otherwise, don’t change it, but still
-- prepend it to the result of normalizing
-- the remainder of the string ‘cs’.
else c : normalizeCase cs
或者,使用 map
:
normalizeCase :: String -> String
-- Given any string:
normalizeCase s
-- For each character:
= map
-- If it’s uppercase, lowercase it.
(\ c -> if c >= 'A' && c <= 'Z'
then chr (ord c + 32)
else c)
-- Over the whole string.
s
Char
可以直接比较(c >= 'A'
),这样可读性更好,但是如果你希望你也使用ord
进行比较,那就是ord c >= 65
.
我知道您不应该为此任务使用任何其他标准函数,但为了将来参考,也可以使用 Data.Char
中的 toLower
非常直接地实现:
import Data.Char (toLower)
normalizeCase :: String -> String
normalizeCase s = map toLower s
-- Alternatively, a point-free/eta-reduced version:
normalizeCase = map toLower
对于删除非字母数字字符的额外任务,您可以使用 filter
、带有保护条件的列表理解,或者自己编写直接递归版本。
需要编写一个程序来检查给定字符串是否为回文,无论大小写是否不同,它都应该可以工作,并且应该忽略非字母数字字符,仅使用 Data.char 中的 ord 和 chr 函数和常规功能,仅此而已。我能够创建常规回文检查器:
reverseStr::String->String
reverStr s | s == [] = []
reverseStr (h:t) = reverseStr t ++ [h]
isPalindrome :: String -> Bool
isPalindrome s = s == reverseStr s
我已经开始研究一个函数来标准化大小写:
normalizeCase::String->String
normalizeCase h | h == [] = []
normalizeCase (h) = if ord h > 64 && ord h < 123
then map (chr $ (ord h + 32)) [h]
else h
但是我得到了这些错误:
• Couldn't match expected type ‘Char -> Char’
with actual type ‘Char’
• In the first argument of ‘map’, namely ‘(chr $ (ord h + 32))’
In the expression: map (chr $ (ord h + 32)) [h]
In the expression:
if ord h > 64 && ord h < 123 then
map (chr $ (ord h + 32)) [h]
else
h
|
6 | then map (chr $ (ord h + 32)) [h] | ^^^^^^^^^^^^^^^^^^
• Couldn't match type ‘Char’ with ‘[Char]’
Expected type: String
Actual type: Char
• In the expression: h
In the expression:
if ord h > 64 && ord h < 123 then
map (chr $ (ord h + 32)) [h]
else
h
In an equation for ‘normalizeCase’:
normalizeCase [h]
= if ord h > 64 && ord h < 123 then
map (chr $ (ord h + 32)) [h]
else
h
|
7 | else h | ^
我对 Haskell 还是很陌生,不知道如何正确实施 ord 或 chr 以便它与此检查器一起工作,所以任何帮助将不胜感激!
在此代码中:
normalizeCase::String->String
normalizeCase h | h == [] = []
normalizeCase (h) = if ord h > 64 && ord h < 123
then map (chr $ (ord h + 32)) [h]
else h
您的第二个模式 (h)
(仅相当于 h
)匹配 任何 列表(只要它尚未与第一个模式匹配, h | h == []
);所以 h
是一个列表,ord h
没有意义,因为 ord
期望 Char
,而不是 [Char]
.
假设 h
是一个字符,那么 chr $ ord h + 32
也是一个字符,但是 map
期望 函数 作为它的第一个参数;这是预期 Char -> Char
但你给了 Char
的错误来源。对于 map
的第二个参数,您传递 [h]
,它是单个元素 h
的列表(在您的代码中也是一个列表,因此您提供 [[Char]]
当你想要 [Char]
).
同时假设 h
是一个字符,您的条件 ord h > 64 && ord h < 123
匹配 uppercase A
和 lowercase 之间的任何字符 z
,包括几个你不想要的字符([]^_`
)。 h
是字符的 列表 这一事实是错误的来源,即 Char
是预期的,但你给出了 [Char]
.
您似乎也在将递归样式与 map
混合使用——在这种情况下,您应该 或者 使用 map
或者 用例定义函数。
下面是您的代码在修复这些错误后的样子。一、使用递归:
normalizeCase :: String -> String
-- Given an empty list, return an empty list.
-- This happens if the original input was empty,
-- or when we reach the end of the recursion.
normalizeCase [] = []
-- Given a non-empty list,
-- test the first character ‘c’.
normalizeCase (c : cs) = if c >= 'A' && c <= 'Z'
-- If it’s uppercase, lowercase it and
-- prepend it to the result of normalizing
-- the remainder of the string ‘cs’.
then chr (ord c + 32) : normalizeCase cs
-- Otherwise, don’t change it, but still
-- prepend it to the result of normalizing
-- the remainder of the string ‘cs’.
else c : normalizeCase cs
或者,使用 map
:
normalizeCase :: String -> String
-- Given any string:
normalizeCase s
-- For each character:
= map
-- If it’s uppercase, lowercase it.
(\ c -> if c >= 'A' && c <= 'Z'
then chr (ord c + 32)
else c)
-- Over the whole string.
s
Char
可以直接比较(c >= 'A'
),这样可读性更好,但是如果你希望你也使用ord
进行比较,那就是ord c >= 65
.
我知道您不应该为此任务使用任何其他标准函数,但为了将来参考,也可以使用 Data.Char
中的 toLower
非常直接地实现:
import Data.Char (toLower)
normalizeCase :: String -> String
normalizeCase s = map toLower s
-- Alternatively, a point-free/eta-reduced version:
normalizeCase = map toLower
对于删除非字母数字字符的额外任务,您可以使用 filter
、带有保护条件的列表理解,或者自己编写直接递归版本。