2011-03-30 141 views
1

我在练习中遇到了麻烦,我应该定义一个函数,它将输入的整数,字符和字符串作为输入,并返回将整个字符串中的字符放置在由整数指定的位置的结果,例如,给函数3,'a'"haskell"应该导致"hasakell"递归函数

putinto :: Int -> Char -> String -> String 
putinto 
+7

告诉我们,你试过了什么? – 2011-03-30 10:36:44

+2

你在问什么编码/编程语言? – Deele 2011-03-30 10:37:11

+0

递归在哪里? – Fender 2011-03-30 10:37:55

回答

3
int j = 3; 
char a = 'a'; 
string x = "haskell"; 

string part1 = x.Substring(0, j); 
string part2 = x.Substring(j); 
string result = part1 + a + part2; 

这港岛线做在C#中招

+1

-1:这不是Haskell。 – 2011-03-30 10:49:52

+0

抱歉不明白,它必须haskell,没有听说过,我很抱歉 – 2011-03-30 10:51:54

+3

+1:一次回答,其中Haskell没有明确标记为要求。 – Boris 2011-03-30 11:38:42

6

想想这样:具有其中第一个元素被称为列表“x”和列表的其余部分被称为“XS” (在Haskell中,这将被写为(x:xs)),您要么将给定的值预先添加到位置列表中为0.否则,您会对列表的剩余部分进行递归调用(并减少该poisition)。

putinto :: Int -> a -> [a] -> [a] 
putinto 0 value list = value : list 
putinto n value (x:xs) = x : putinto (n-1) value xs 

如果它看起来很奇怪,(x:xs)实际上是一个“解构”列表。 x代表列表中的第一个元素,xs('s'表示'复数',所以它是'x'的复数)是列表的其余部分。

因此,与零调用它实际上将预先准备的给定值,如

putinto 0 'a' "haskell" -- yields 'ahaskell' 

两个调用将是:

putinto 2 'a' "haskell" 
-- same as 'h' : putinto 1 'a' "askell" 
-- same as 'h' : 'a' : putinto 0 'a' "skell" 
-- same as 'h' : 'a' : 'a' : "skell" 
-- same as "haaskell" 

你仍然需要关心错误检查(什么如果给定的位置是否定的,或者大于列表长度?)。

+0

re:错误检查。在Haskell中,这不能仅仅是“加入”,函数的类型签名必须改变为像'Int - > a - > [a] - > Maybe [a]。由于这不是问题的类型签名,所以我建议最好的做法是快速失败。 – 2011-03-31 05:18:56

3

在为涉及Haskell中的列表的问题编写明确的递归解决方案之前,应该检查是否可以使用PreludeData.List中的列表函数完成相同的任务。在这种情况下splitAt可以帮助:

splitAt 3 "haskell" 
("has","kell") 

因此您的问题通过拆分,consing和追加迎刃而解:

putInto :: Int -> Char -> String -> String 
putInto n c xs = let (ys,zs) = splitAt n xs in ys ++ (c:zs) 

只是为了好玩,上面也可以在自由点式写使用应用性实例(-> r)

putInto :: Int -> Char -> String -> String 
putInto n c = ((++) . fst <*> (c:) . snd) . splitAt n 
+0

非常感谢大家。 – steven 2011-03-31 11:52:08

0

我想这应该很容易阅读。我列举了以下解释:

1. putInto :: Int -> Char -> String -> String 
2. putInto 0 a xs  = a:xs 
3. putInto _ a []  = [a] 
4. putInto n a (x:xs) = x : putInto (n-1) a xs 

这是怎么回事?第一行是类型签名。第二行检查是否希望将字符设置在前面(即索引0)。

第三和第四行是我们希望在第0个索引后插入它的时间。第三行检查我们要插入的列表是否为空,在这种情况下,我们只返回仅包含a的列表。

在第四行中,我们知道我们字符串的第一个索引仍然是第一个索引,所以我们只是在尾部递归,在需要的时候减少n

+1

请注意,当索引大于字符串的长度时,这会引发错误。 – dave4420 2012-03-27 08:13:50

+0

修正了通过添加一个子句。如果n为负,它仍然会进入无限循环。 – Undreren 2012-03-27 09:02:26

+0

如果'n'是负数,'a'将被添加到列表的末尾。 – dave4420 2012-03-27 09:06:18