我想從像這樣的字串中消除連續的重復項 f "aaabbbcccdeefgggg" = "abcdefg"
這是我的代碼
f :: String -> String
f "" = ""
f "_" = "_"
f (x : xs : xss)
| x == xs = f (xs : xss)
| otherwise = x : f (xs : xss)
我得到了錯誤的非詳盡模式,我認為它來自第二行,當它只剩下 1 個字符時,程式不知道如何處理。我應該如何解決它?
uj5u.com熱心網友回復:
該"_"模式不匹配帶有任何字符的字串,它匹配包含下劃線的字串。
您可以將[_]其用作單例字串的模式,因此:
f :: String -> String
f "" = ""
f s@[_] = s
f (x : xs : xss)
| x == xs = f (xs : xss)
| otherwise = x : f (xs : xss)
這里我們用s@一個字符來捕獲字串 as s。
或者我們可以簡化為:
f :: String -> String
f (x : xs : xss)
| x == xs = f (xs : xss)
| otherwise = x : f (xs : xss)
f s = s
uj5u.com熱心網友回復:
我想從像這樣的字串中消除連續的重復項
f "aaabbbcccdeefgggg" = "abcdefg"
您可以將相等的字母分組(通過Data.List.group),然后取每個組中的第一個(通過map head,它適用head于串列的每個元素并回傳結果串列):
import Data.List (group) -- so we write group instead of Data.List.group
map head $ group "aaabbbcccdeefgggg"
這可以看作是對輸入的應用map head 后的應用。因此,您可以定義為這兩個函式的組合:groupStringf
f :: String -> String
f = map head . group
為了完整起見,因為您似乎是 Haskell 的新手,這里有一些細節:
Data.List.group "aaabbbcccdeefgggg"回傳["aaa","bbb","ccc","d","ee","f","gggg"];f $ a b cf (a b c)與;相同.是合成運算子,它是這樣的(f . g) x == f (g x)。
uj5u.com熱心網友回復:
或者,如果您不處理可能未處理的事情,您可以使其更簡單:
f :: String -> String
f (x:y:xs) | x == y = f (y:xs)
f (x:xs) = x:f xs
f _ = ""
uj5u.com熱心網友回復:
為避免不必要地向前看,您不應嘗試匹配前兩個元素。相反,請跟蹤最新的元素。
f :: Eq a => [a] -> [a]
f = start
where
start [] = []
start (x : xs) = x : go x xs
go _old [] = []
go old (x : xs)
| x == old
= go old xs
| otherwise
= x : go x xs
如果你愿意,你也可以把它寫成fold,你可以在其中跟蹤你是否已經看到一個元素還使用 a Maybe:
f :: Eq a => [a] -> [a]
f xs = foldr go stop xs Nothing
where
stop _ = []
go x r (Just old)
| x == old = r (Just old)
go x r _ = x : r (Just x)
如果重新排列一下,有些人可能會發現折疊更容易閱讀。
f :: Eq a => [a] -> [a]
f xs = (foldr go stop xs) Nothing
where
stop :: Maybe a -> [a]
stop = \_ -> []
go :: a -> (Maybe a -> [a]) -> (Maybe a -> [a])
go x r = \acc -> case acc of
Just old
| x == old -> r (Just old)
_ -> x : r (Just x)
uj5u.com熱心網友回復:
你也可以使用foldl. 邏輯是:將累加器的最后一個元素與當前元素進行比較。
f :: Eq a => [a] -> [a]
f xs = foldl (\x y -> if last x == y then x else x [y] ) [head xs] xs
在這里,我們用 啟動我們的累加器[head x]。
根據@dfeuer 提示,我更改了我的解決方案:
-- with foldl
f :: Eq a => [a] -> [a]
f xs = snd $ foldl opr (Nothing, []) xs
where
opr (Just old, acc) n
| old == n = (Just old, acc)
| otherwise = (Just n, acc [n])
opr (Nothing, acc) n = (Just n, acc [n])
-- with foldr
f2 :: Eq a =>[a] -> [a]
f2 xs = snd $ foldr opr (Nothing, []) xs
where
opr n (Just old, acc)
| old == n = (Just old, acc)
| otherwise = (Just n, n:acc)
opr n (Nothing, acc) = (Just n, n:acc)
感謝@dfeuer,我學到了很多新東西。這是基于評論的第三個版本:
-- with foldl
f :: Eq a => [a] -> [a]
f xs = snd $ foldl opr (Nothing, []) xs
where
opr (old, acc) n =
( Just n,
case old of
Just o
| o == n -> acc
| otherwise -> acc [n]
Nothing -> acc [n]
)
-- with foldr
f :: Eq a => [a] -> [a]
f xs = snd $ foldr opr (Nothing, []) xs
where
opr n (old, acc) =
( Just n,
case old of
Just o
| o == n -> acc
| otherwise -> n : acc
Nothing -> n : acc
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/417811.html
標籤:
上一篇:如何將字串轉換為元組
