第一次發帖,長期潛伏。
作為借口:在此之前,我撰寫了一個函式來計算文本中一對單詞出現的次數,該函式計算整個文本中的每一對單詞。像這樣:
pairCounter = map (\x -> (head x,length x)). groupTuples . sort
此函式回傳:[((String, String), Int)] 第一個/第二個字串是對中的 word1/2,并且 Int 是可以找到多少次,或者如果您愿意,則是對的“計數”。
我現在想做的是創建一個函式,該函式只將“鄰居”回傳給任何給定的單詞。例如:
neighbours [(("red","car"),2),(("house","red"),1)] "red"
應該回傳[("car",2),("house",1)]或重新排序此串列。
所以基本上; 我們已經建立了任何給定詞的所有對,但現在我只想挑出這個詞的鄰居和它的頻率。
到目前為止,我已經考慮過以這種方式使用過濾器:
filter (\(x, y) -> x /= c || y /= c)
--^(I have no idea if this is syntax correct but it is just to give myself an idea where to start)
然而,我發現很難想出一種方法來使用過濾器并且還包括我鄰居的計數,即我的 Int 論點。
請讓我知道這是否違反任何規則或類似規則,謝謝。
uj5u.com熱心網友回復:
一種非常慣用的方式是通過串列理解:
neighbours :: Eq a => [((a, a), b)] -> a -> [(a, b)]
neighbours items query =
[ (neighbor, count)
| ((s1, s2), count) <- items
, (self, neighbor) <- [(s1, s2), (s2, s1)]
, self == query
]
實際上,我可能會將引數按另一種順序排列,以匹配現有庫中使用的約定并縮短名稱,使其輕松地放在一行中:
neighbours :: Eq a => a -> [((a, a), b)] -> [(a, b)]
neighbours x xs = [(x4, n) | ((x1, x2), n) <- xs, (x3, x4) <- [(x1, x2), (x2, x1)], x3 == x]
我懷疑你不關心順序的部分會出現在你代碼的其他部分,所以另外我會考慮拆分一個對稱的部分。如果稍后您決定對出現在兩個訂單中的對進行標準化并將它們的計數相加或諸如此類的事情,這也將很有幫助,因為您只需更改一個位置即可將該更新傳播給所有消費者。
-- (s)ource, (t)arget, (u)ndirected edge, (w)eight, (w)eighted edge(s)
undirected :: [((a, a), b)] -> [((a, a), b)]
undirected ws = [(u, w) | ((s, t), w) <- ws, u <- [(s, t), (t, s)]]
neighbours :: Eq a => a -> [((a, a), b)] -> [(a, b)]
neighbours x xs = [(t, w) | ((s, t), w) <- undirected xs, s == x]
或者,您可能決定從一開始就使圖無向。
import qualified Data.Map as M
-- export UPair the type but not UPair the constructor
data UPair a = UPair a a
deriving (Eq, Ord, Read, Show, Functor, Foldable, Traversable)
-- this is strict. can also make a lazy variant
upair :: Ord a => a -> a -> UPair a
upair a a' = if a < a' then UPair a a' else UPair a' a
pairCounter :: [a] -> M.Map (UPair a) Int
pairCounter as = M.fromListWith ( ) $ zipWith (\a a' -> (upair a a', 1)) as (tail as)
uj5u.com熱心網友回復:
因此,對于給定的單詞,c您應該保留第一個String或第二個String等于 的專案c。我們應該使用as 模式,因為外部的 2-tuple 有一個 2-tuple作為第一項,一個作為第二項的元素。((s1, s2), v)StringsInt
我們可以concatMap :: Foldable t => (a -> [b]) -> t a -> [b]使用一個函式,如果匹配,如果匹配,如果兩個元素都不匹配,則回傳空串列:[(s2, v)]s1[(s1, v)]s2
我們因此過濾:
neighbors :: (Foldable f, Eq a) -> f ((a, a), b) -> a -> [(a, b)]
neighbors items query = concatMap f items
where f ((s1, s2), v)
| query == s1 = [(s2, v)]
| query == s2 = [(s1, v)]
| otherwise = []
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/370708.html
