2013-05-12 123 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"]