我想使用F#在一组单词中找到辅音与元音的接近程度。例如,在单词“ top”中,T是元音的(-1:1),P是元音的(1:1)。
相对于最近的元音,对中的第一个数字是位置,第二个数字是其在该位置的次数。
在“辅音”中,C为(-1:1),N为(1:3),(-2:1),(-1、1),S为(2:1),(-1 :1),(3:1),T为(2:1)。
我怀疑我必须结合使用groupBy,findIndex和countBy。
type ConsonantPos = { Name: string
BeforeVowel: int
AfterVowel: int }
let isVowel (x:string) =
List.contains x ["a";"e"; "i"; "o"; "u"]
let consonantPosVsVowel x lst =
let rec getConsonanatPos x beforeVowel afterVowel currentPos lst =
match lst with
| [] -> {Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
| h::t ->
if isVowel h then
{Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
else
getConsonanatPos x (beforeVowel - 1) (afterVowel + 1) (currentPos + 1) t
getConsonanatPos x 0 0 0 lst
["b"; "a"; "c"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -1; AfterVowel = 1;}
["b"; "c"; "d"; "e"; "f"; "g"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -3; AfterVowel = 3;}
截至2018年11月21日,这两个建议对于我最初指定的问题均行之有效。
当然,这个问题只是我正在编写的程序的一部分。当我扩展程序并浏览数据BEEP时,一种响应被证明更易于重用:这就是我标记为答案的响应。
事实证明,我的问题是我缺乏理解并且无法使用收藏集。
答案 0 :(得分:2)
尝试一下:
let isVowel (x:char) =
List.contains x ['a';'e'; 'i'; 'o'; 'u']
let countConsonants (word:string) =
let vowelsp, consonants =
word
|> Seq.mapi(fun i c-> c,i )
|> Seq.toArray
|> Array.partition (fst >> isVowel)
let vowels = vowelsp |> Array.map snd
consonants
|> Seq.collect (fun (c,i) ->
match vowels |> Array.tryFindIndex ((<) i) with
| None -> [ vowels.Length - 1 ]
| Some j -> [ j - 1 ; j ]
|> Seq.choose (fun j ->
if j < 0 then None else
Some(c, i - vowels.[j])
)
)
|> Seq.countBy id
|> Seq.map (fun ((l,p), c) -> (l,(p, c)) )
|> Seq.groupBy fst
|> Seq.map (fun (l, s) -> l, s |> Seq.map snd |> Seq.toArray)
|> Seq.toArray
"consonants"
|> countConsonants
|> Seq.iter (printfn "%A")
答案 1 :(得分:1)
这是一种略有不同的方法,它以不同的方式分解任务。
let genTail2 xss =
let rec aux accl accr = function
| [] -> List.rev accr
| x::xs -> aux (x::accl) ((x, (xs, accl))::accr) xs
aux [] [] xss
// val genTail2 : xss:'a list -> ('a * ('a list * 'a list)) list
let dist2 pred (x, (ls, rs)) =
let rec aux n i = function
| [] -> None
| y::ys -> if pred y then Some(x, n) else aux (n + i) i ys
aux -1 -1 ls, aux 1 1 rs
// val dist2 :
// pred:('a -> bool) ->
// x:'b * ('a list * 'a list) -> ('b * int) option * ('b * int) option
let tuple2List = function
| None, None -> []
| Some x, None | None, Some x -> [x]
| Some x, Some y -> [y; x]
// val tuple2List : 'a option * 'a option -> 'a list
let isVowel = ResizeArray['a';'e';'i';'o';'u'].Contains
// val isVowel : (char -> bool)
"consonants"
|> fun s -> s.ToLower()
|> Seq.toList
|> genTail2
|> List.filter (fst >> isVowel >> not)
|> List.collect (dist2 isVowel >> tuple2List)
|> Seq.groupBy fst
|> Seq.map (fun (x, xs) -> x, Seq.countBy snd xs)
|> Seq.iter (printfn "%A")