2011-03-30 143 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