2013-05-12 122 views
4

我有一個關於Haskell的問題,它一直在困住我的大腦。我目前需要編寫一個從字符串列表中刪除字符串的函數,即"word"["hi", "today", "word", "Word", "WORD"]返回列表["hi", "today", "Word", "WORD"]。我不能使用任何高階函數,只能使用原始遞歸。從Haskell中的字符串列表中刪除一個字符串

有關問題的思考,我想,也許,你搜索的第一個字符串的頭部,如果匹配"w"然後從尾下一頭進行比較,看是否匹配"o"我可以用遞歸解決。但後來我很快意識到,畢竟這些工作,你將無法刪除完整的字符串"word"

我的問題確實是如何比較列表中的整個字符串,而不是僅將某個元素與某個時間點的元素進行比較:removeWord (x:xs)。它甚至有可能嗎?我是否必須編寫幫助函數來幫助解決方案?

+2

你的列表中包含字符串其實並不重要這裏。嘗試解決問題,例如首先列出「Int」,那麼它應該只是改變類型簽名以使其適用於字符串列表。 – hammar 2013-05-12 00:28:15

+3

將'(x:xs)'與'[「hi」,「today」,「word」,「Word」,「WORD」]匹配時,'x'變成'「hi」'而'xs'變成'[「今天」,「單詞」,「單詞」,「文字」]'。也就是說,它通過字符串匹配字符串,而不是逐個字符。這是有效的,因爲你有一個* list *的字符串,而不僅僅是一個大字符串。 – 2013-05-12 00:28:31

+0

哦,我明白了!非常感謝你這是它給我帶來麻煩的地方。我認爲這只是第一個元素,而不是整個單詞。這清除了一切! – Phirip 2013-05-12 00:44:54

回答

2

考慮基本情況:從空列表中刪除單詞將是空列表。這可以寫得很簡單:

removeWord [] _ = [] 

現在考慮一下列表不爲空的情況。你match這與x:xs。您可以使用a guard這兩個條件之間進行選擇:

  1. x是要刪除的字。 (x == word
  2. x是不是你想要刪除的單詞。 (otherwise
+0

我認爲'(x:xs)'x只會匹配列表中的第一個元素,因此在[「Hi」,「word」]中,x會返回H,否? – Phirip 2013-05-12 00:38:47

+1

@Phirip:'[「Hi」,「word」]'是兩個元素的列表。第一個元素是「Hi」。第二個元素是「」字「'。對於'(x:xs)','x'會是'「Hi」'。如果你使用'((x:xs):ys)',你只會得到'H'。 – icktoofay 2013-05-12 00:41:00

+0

哦,我明白了!非常感謝你這是它給我帶來麻煩的地方。我認爲這只是第一個元素,而不是整個單詞。這清除了一切! – Phirip 2013-05-12 00:44:15

3

你不需要輔助函數,儘管你可以寫一個函數,如果你想的話。你基本上有3個條件:

  1. 你得到一個空的列表。
  2. 你得到一個列表,其第一個元素是你想要刪除的元素。
  3. 你得到一個列表,其第一個元素是其他任何東西。

在其他語言中,你將與一組if-else語句做到這一點,或用case陳述或cond。在這兩個條件下,這種功能在正確的結果

remove_word_recursive:: String -> [String] -> [String] 
remove_word_recursive _ []        = [] 
remove_word_recursive test_word (x:xs) | test_word == x = what in this case? 
remove_word_recursive test_word (x:xs)     = what in default case? 

填充,你應該做的:在Haskell中,你可以用守衛做到這一點。

我認爲你要找的是一個特殊情況下的函數尋找這個問題的字符串過濾器:Haskell - filter string list based on some conditions。閱讀關於接受的答案的一些討論可能會幫助您更好地理解Haskell。

+3

請不要傳播'underscore_naming_convention','camelCaseConvention'似乎是事實上的標準。 – dflemstr 2013-05-12 11:04:38

+0

啊,好的。我沒有意識到Haskell社區的標準,而'underscore_naming_convention'是我所在語言的標準。是否有人在討論爲什麼'camelCaseConvention'對Haskell更爲優越? – pcurry 2013-05-12 15:09:11

+1

[Haskell編程指南](http://www.haskell.org/haskellwiki/Programming_guidelines)構成某種權威來源,並且'base'庫(帶有'Prelude')是使用該命名約定和Hackage上的大多數Haskell庫。下劃線通常保留用於丟棄值的函數版本(即'mapM_'而不是'_ < - mapM')。 – dflemstr 2013-05-12 16:34:21

2

由於您想要刪除列表元素,因此使用列表理解很容易。

myList = ["hi", "today", "word", "Word", "WORD"] 
[x | x <- myList, x /= "word"] 

結果是:

["hi","today","Word","WORD"]