【发布时间】:2019-08-28 00:54:19
【问题描述】:
我正在尝试创建一个函数,它结合给定整数列表的字符串。例如,假设给定函数[1,2,3],那么输出将是" ***"。基本上,每个数字代表一个*,前面有空格。所以数字 5 将是 " *",即 4 个空格后跟 *。但是,我得到了一个列表,我不能把它们都++ 放在一起,因为字符串会打乱顺序。
我的想法是从获取列表中的第一个元素开始,然后递归地将其作为字符串发送回来。所以对于[1,2,3],我会用String = " *" 发送回函数[2,3]。接下来,对于每个元素,我检查字符串 -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 " ****"
" ** * *"
我不明白为什么它对前 2 个元素是正确的,然后对之后的任何东西都不正确。我已经对其进行了多次跟踪,但一切似乎都应该可以正常工作。
编辑 解决方案:
makeStr :: [Integer] -> String
makeStr [] = ""
makeStr (x:xs)
| x == 0 = "*" ++ makeStr (map (subtract 1) xs)
| x /= 0 = " " ++ makeStr (map (subtract 1) (x:xs))
【问题讨论】:
-
你能写一个函数
mergeStars :: String -> String -> String来获取其中两个星表并生成一个将两者的星组合起来的函数吗?提示:你可能想使用zipWith。 -
我会找到列表的最大值,然后
map在枚举[0..maxOfList]上使用一个检查数字是否在输入列表中的函数,并生成'*'或 @987654344 @ 相应地。 -
[2,2]的输出是什么?对于[3,1]? -
看起来
s中的makeStr (x:xs) s从未使用过。类型签名不能只是makeStr :: [Integer] -> String而不是makeStr :: [Integer] -> String -> String?
标签: haskell functional-programming