Я пытаюсь создать функцию, которая объединяет строки с учетом списка целых чисел. Например, скажем, функции было присвоено [1,2,3]
, тогда результат будет " ***"
. По сути, каждое число представляет собой *
с пробелами перед ним. Таким образом, число 5
будет " *"
, то есть 4 пробела, за которыми следует *
. Тем не менее, мне дали список, и я не могу просто ++
их всех вместе, потому что строки портят порядок.
Моя идея состояла в том, чтобы начать с первого элемента в списке и рекурсивно отправить его обратно в виде строки. Поэтому для [1,2,3]
я бы отправил обратно в функцию [2,3]
с String = " *"
. Далее, для каждого элемента я проверяю, равна ли длина строки -1 <=
следующему элементу (- 1, потому что 0 включено). В списке, который я даю функции, это всегда будет иметь место (список всегда будет числом от 0 до 9, увеличиваясь, и НЕТ повторений). Затем я бы ++
снова отправил исходную строку в вызов функции, чтобы сделать рекурсивное утверждение. Я делал это, пока ничего не осталось. Вот что я сделал:
makeStr :: [Integer] -> String -> String
makeStr [] _ = ""
makeStr (x:xs) s
| null xs && s == "" = getStar ((fromIntegral x)) "*"
| null xs && s /= "" = s ++ getStar ((fromIntegral x) - (length s)) "*"
| s == "" = makeStr xs (getStar ((fromIntegral x) - ((length s))) "*")
| length s - 1 <= (fromIntegral x) = s ++ makeStr xs (getStar ((fromIntegral x) - ((length s))) "*")
Примечание: getStar - это простая функция, которая принимает число и «*» и возвращает строку с правильным количеством пробелов. Он имеет декларацию getStar :: Int -> String -> String
. Эта функция работает отлично, я тестировал ее много раз, и я действительно не верю, что это проблема, поэтому я не включил ее.
Пример функции getStar:
getStar 3 "*"
" *"
некоторые примеры входов с ожидаемыми выходами:
makeStr [1,2,3] ""
" ***"
makeStr [0,2,3] ""
"* **"
makeStr [1,2,3,4] ""
" ****"
makeStr [0,9] ""
"* *"
Вывод моей программы некорректен для любого списка из 2 элементов.
makeStr [0,1] "" -- correct
"**"
makeStr [1,2,3] "" -- incorrect, should be " ***"
" ** *"
makeStr [1,2,3,4] "" -- incorrect, should be " ****"
" ** * *"
Я не могу понять, почему это правильно для первых двух элементов, а затем для чего-то неправильного после. Я проследил это несколько раз, но кажется, что все должно работать нормально.
Редактировать
Решение:
makeStr :: [Integer] -> String
makeStr [] = ""
makeStr (x:xs)
| x == 0 = "*" ++ makeStr (map (subtract 1) xs)
| x /= 0 = " " ++ makeStr (map (subtract 1) (x:xs))