基本上,我有一个由字符串组成的列表列表,这些字符串仅是数字,例如[“ 22”,“ 333”,“ 2”],我想将其转换为字符串“ bea”。就像旧手机一样,如果您按两次2则得到b,如果按4则得到j,就象旧手机一样。只能使用前奏功能
我这样尝试过
numbers ws [] = ws
numbers ws (x:xs) = if head "2ABC" == head x
then ws ++ "2ABC" !! length x ++ numbers ws xs
else if head "3DEF" == head x
then ws ++ "3DEF" !! length x ++ numbers ws xs
....
但是这给了我错误,所以您可以帮助我吗?
答案 0 :(得分:6)
一个典型的错误是在一个函数中实现了太多的逻辑。与其尝试将整个解码工作转换成numbers
函数,不如将任务拆分为可重用的组件,这样它们就易于理解,调试和重用,可能会更好。
作为第一个功能,我们可以将数字映射到包含字符的String
上,例如:
digtoseq :: Char -> String
digtoseq '2' = "abc"
digtoseq '3' = "def"
digtoseq '4' = "ghi"
digtoseq '5' = "jkl"
digtoseq '6' = "mno"
digtoseq '7' = "pqrs"
digtoseq '8' = "tuv"
digtoseq '9' = "wxyz"
digtoseq '0' = " "
我们可以在此处添加其他字符,例如'.'
,以指定每个电话键后面的顺序。
现在,我们可以实现一个利用digtoseq
的函数,例如digstrtoseq
:
digstrtoseq :: String -> Char
digstrtoseq (x:xs) = digtoseq x !! length xs
在这里,我们采用字符串的长度以及第一个字符,然后遍历字符串digtoseq x
,以获得第n-1
个元素(使用{{1} }输入字符串的长度)。因此,对于n
,我们得到:
"22"
因此,现在只需Prelude> digstrtoseq "22"
'b'
Prelude> digstrtoseq "33"
'e'
Prelude> digstrtoseq "2"
'a'
在输入字符串上ping此函数即可。
map
然后我们获得:
numbers :: [String] -> String
numbers = map digstrtoseq
请注意,这里我们做了一些假设,其中一些可以通过重写函数来改善,而其他一些则可以通过更改输入的类型来更好地解决:
Prelude> numbers ["22", "33", "2"]
"bea"
; "2222"
不会出现; "231"
; "~"
。大量的假设源自以下事实:我们在这里使用""
作为输入类型,这提供了很大的自由度。是的,在这种情况下可能会引发错误或返回[String]
,但最好定义如下类型:
Nothing
,然后输入data Key = Two | Three | Four | Five | Six | Seven | Eight | Nine | Zero
作为输入,因为假设(2)和(3)可以通过输入类型简单地“保证”。
答案 1 :(得分:2)
威廉击败了我,但这就是我想出的。您可能还是想完成键盘
numToChar :: Char -> Int -> Char
numToChar '2' i = "abc" !! (i - 1)
numToChar '3' i = "def" !! (i - 1)
numToChar '4' i = "ghi" !! (i - 1)
numToChar '5' i = "jkl" !! (i - 1)
numToChar '6' i = "mno" !! (i - 1)
numToChar '7' i = "pqrs" !! (i - 1)
numToChar '8' i = "tuv" !! (i - 1)
numToChar '9' i = "wxyz" !! (i - 1)
numbers n = [numToChar (head x) (length x) | x <- n]
答案 2 :(得分:0)
确实有更直接的翻译或映射方法。 ASCII字符集可用于此目的。此功能很强大。我可以看到的唯一限制是ASCII字符集的长度。假设是我们无法键入将不使用的内容。第一位数字只重要。以后可以使用任何东西。
td=\(s:sx)->[toEnum (47+d+e+(length sx))::Char|d<-[fromEnum s],e<-[2*(mod d 50) + if d > 55 then 1 else 0]]
以任何方式使用td。
concat $ map td ["222","33","9999","4"]
“ cezg”