Преобразуйте строку из чисел в слова, как старые телефоны - PullRequest
0 голосов
/ 24 октября 2018

В основном у меня есть список списков, состоящих из строк, которые являются только числами, такими как ["22", "333", "2"], и я хочу преобразовать его в строку "bea".Думайте об этом, как о старых телефонах, если вы дважды нажмете 2, вы получите ab, если вы нажмете 4, когда получите aj, вот так.Можно использовать только функции прелюдии

Я пробовал вот так

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
....

Но это дает мне ошибки, так что вы можете помочь мне, ребята?

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Виллем опередил меня, но вот что я придумал.Вы можете завершить клавиатуру, хотя

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]
0 голосов
/ 26 октября 2018

Действительно, существуют более прямые методы перевода или картирования.Для этого можно использовать набор символов 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"

0 голосов
/ 24 октября 2018

Классическая ошибка заключается в реализации слишком большого количества логики в одной функции.Вместо того, чтобы пытаться выполнить полное декодирование в функцию 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 -й элемент (с n длиной входной строки).Таким образом, для "22" мы получаем:

Prelude> digstrtoseq "22"
'b'
Prelude> digstrtoseq "33"
'e'
Prelude> digstrtoseq "2"
'a'

, так что теперь map проверяет эту функцию на строке ввода:

numbers :: [String] -> String
numbers = map digstrtoseq

и затем мыполучить:

Prelude> numbers ["22", "33", "2"]
"bea"

Обратите внимание, что здесь мы сделали некоторые предположения, некоторые из которых можно улучшить, переписав функции, другие лучше решить, изменив тип ввода:

  1. мы предполагаем, что ни одна строка не имеет длину больше, чем длина последовательности за ней, поэтому "2222" не произойдет;
  2. мы предполагаем, что символ в строковом элементе повторяется по всей строке, поэтому"231" не произойдет;
  3. мы предполагаем, что строки содержат только допустимые цифры, поэтому нет "~";
  4. мы предполагаем, что каждая строка содержит хотя бы один символ, поэтому "".

Большая часть предположений проистекает из того факта, что мы здесь используем [String] в качестве типа ввода, что дает большую свободу.Да, возможно выдавать ошибки или возвращать Nothing в этом случае, но может быть лучше определить тип, например:

data Key = Two | Three | Four | Five | Six | Seven | Eight | Nine | Zero

, а затем в качестве ввода взять [(Key, Int)], с тех пор предположения(2) и (3) просто «гарантированы» через тип ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...