2008-12-31 83 views
4

我需要能夠編寫顯示重複的單詞從字符串的函數,在其發生的順序返回一個字符串列表,而忽略非字母顯示在Haskell重複的單詞

例如,在擁抱的列表提示

repetitions :: String -> [String] 

repetitions > "My bag is is action packed packed." 
output> ["is","packed"] 
repetitions > "My name name name is Sean ." 
output> ["name","name"] 
repetitions > "Ade is into into technical drawing drawing ." 
output> ["into","drawing"] 

回答

8

要將字符串拆分爲單詞,請使用words函數(在前奏中)。 消除非單詞字符,filterData.Char.isAlphaNum。 將此列表連同其尾部一起拉到相鄰對(x, y)。 摺疊列表,包含一個新列表,其中包含所有x,其中x == y

成才,如:

repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l 
    where l = map (filter isAlphaNum) (words s) 

我不知道這樣的作品,但它應該給你一個大概的瞭解。

+0

這個確定的工作,但我發現我沒有被教過地圖和欺騙function.Could這個問題可以回答沒有這兩個功能?我正在爲我的考試練習它不是一項家庭作業。 – SeanHill 2008-12-31 10:12:26

+1

「dupe」只是一個輔助函數,它只是檢查兩個值是否相同。然而,「地圖」可能是Haskell中最重要的功能或任何函數式編程,所以最好只是在考試中瞭解它。 – mattiast 2008-12-31 12:12:06

2

我是新來這個語言,所以我的解決辦法是在哈斯克爾老兵眼中的那種醜陋的,但無論如何:

let repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (words (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x))))) 

這部分將從字符串中刪除所有非字母和非空間小號

filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') s 

這人會分割字符串小號單詞和組同樣的話,以列表返回列表清單:

List.group (words s) 

當這部分將刪除所有列表少於兩個元素:

filter (\x -> (length x) > 1) s 

我們將串連所有列表後,一個從中取出一個元素,雖然

concat (map tail s) 
0

這可能是無能的,但它在概念上非常簡單。我假設它尋找像例子那樣的連續重複的單詞。

-- a wrapper that allows you to give the input as a String 
repititions :: String -> [String] 
repititions s = repititionsLogic (words s) 
-- dose the real work 
repititionsLogic :: [String] -> [String] 
repititionsLogic [] = [] 
repititionsLogic [a] = [] 
repititionsLogic (a:as) 
    | ((==) a (head as)) = a : repititionsLogic as 
    | otherwise = repititionsLogic as 
0

建立在什麼亞歷山大·普羅科法爾維回答:

repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (word (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))

刪除不必要的括號:

repetitions x = concat (map tail (filter (\x -> length x > 1) (List.group (word (filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x)))))

使用$來去除更多的括號(各$可以替換左括號如果結束括號在表達式的末尾):

repetitions x = concat $ map tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x

用數據中的函數替換字符範圍。字符,合併CONCAT與地圖:

repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

使用部分和自由點式討好簡化(\x -> length x > 1) to ((>1) . length)。這將length與(> 1)(部分應用的運算符或部分)合併到從右到左管道中。

repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

消除明確的「X」變量,使整體表達點免費電話:

repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)

現在整個功能,從右讀向左,是管道,用於過濾只有阿爾法或分隔符字符,將其拆分爲單詞,將其拆分成組,使用多於1個元素過濾這些組,然後將其餘組減少到每個組的第一個元素。