String 如何检查文本中是否存在短语列表?
我一直在尝试创建一个过滤器,使用递归函数和匹配模式检查文本中是否存在短语列表中的短语,但不知何故,这似乎不起作用。。。也许有人能告诉我为什么String 如何检查文本中是否存在短语列表?,string,list,text,f#,String,List,Text,F#,我一直在尝试创建一个过滤器,使用递归函数和匹配模式检查文本中是否存在短语列表中的短语,但不知何故,这似乎不起作用。。。也许有人能告诉我为什么 let rec matchTails (tail1 : string list) (tail2 : string list) = match tail1, tail2 with | h1::t1 , h2::t2 -> if (h1=h2) then matchTa
let rec matchTails (tail1 : string list) (tail2 : string list) =
match tail1, tail2 with
| h1::t1 , h2::t2 ->
if (h1=h2) then
matchTails t1 t2
else
false
| _, [] -> false
| [],_-> true
let rec check2 (textH: string) (textT: string list) (phrases: string list list) =
match phrases with
|[] -> ()
| h :: t ->
printfn "%s -- %s" (h.Head) (textH)
match h with
|x when x.Length = 1 && x.Head = textH ->
()
|x when x.Head = textH && (matchTails (textT) (x)) ->
printfn "%s" (x.Head)
| _ -> ()
check2 (textH) (textT) (t)
let rec check (phrases : string list list) (text:string list) =
match text with
| [] -> ()
| h :: t ->
check2 (h) (t) (phrases)
check phrases t
let p = [["rolex"]; ["free"; "spins"; "everyday"]; ["free"; "cash"]]
let t = ["hello";"and";"welcome";"to";"our";"annual";"free";"cash";"and";"rolex";"giveaway"]
函数调用:check p t
我编辑了我的问题,修正了一些错误,但是,有了这些列表,程序将unit()作为输出 这里有一些提示:
返回的结果不正确matchTails
我怀疑在所有这些情况下,它都应该返回matchTails [ "asdf1" ] [ "asdf" ] => true matchTails [ "asdf" ] [ "asdf"; "asdf1" ] => true matchTails [ ] [ "" ] => true
。您想要的实现可能是:false
let rec matchTails (phrase : string list) (text : string list) = match phrase, text with | h1 :: t1, h2 :: t2 -> if h1 = h2 then matchTails t1 t2 else false | [ ], _ -> true | _ -> false let matchTails_test () = if not (matchTails [ "" ] [ "" ]) then raise Exception() ...
不是递归调用的,因此只检查第一个短语check2
不是递归调用的,它调用check2并返回check
check2
实际上并不返回任何值(它返回单位)。此外,它的功能与matchTails
重叠-它用短语中的第一个单词检查头部,这就是matchTails
的作用
检查也返回单位,()表示单位
让我们重写检查:
let rec check (phrases : string list list) (text : string list) =
if phrases |> List.exists (fun ph -> matchTails ph text) then
true
else
match text with
| [] -> false
| _ :: tail -> check phrases tail
虽然问题现在已经解决了,但我想指出,将其划分为子问题已经非常充分;令人震惊的是缺乏相关的测试,以及处理每个子问题的单个函数的一些描述性命名
例如,命名(和测试)matchTails
、check2
和check
怎么样
let ps = [["rolex"]; ["free"; "spins"; "everyday"]; ["free"; "cash"]]
let t = ["hello";"and";"welcome";"to";"our";"annual";"free";"cash";"and";"rolex";"giveaway"]
startsWithPhrase ["hello"; "and"] t
containsPhrase ["free"; "cash"] t
containsAnyPhrase ps t
扰流板:
完全使用高级函数(每个函数代替一个递归循环)可能会容易得多。尽管这里的方法稍有不同,将干草堆分成针状大小的薄片,并将每一片与给定的短语进行比较
let containsPhraseHL phrase text =
Seq.windowed (List.length phrase) text
|> Seq.exists (Seq.forall2 (=) phrase)
containsPhraseHL ["free"; "cash"] t
let containsAnyPhraseHL phrases text =
List.exists (fun phrase -> containsPhraseHL phrase text) phrases
containsAnyPhraseHL ps t
在匹配表达式中有h2=h2
。这将始终评估为真。你的意思是h1=h2
?我已经编辑了我的问题,并修复了那些错误,但程序似乎找到了长度为1的短语,而不是更长的短语。。
let containsPhraseHL phrase text =
Seq.windowed (List.length phrase) text
|> Seq.exists (Seq.forall2 (=) phrase)
containsPhraseHL ["free"; "cash"] t
let containsAnyPhraseHL phrases text =
List.exists (fun phrase -> containsPhraseHL phrase text) phrases
containsAnyPhraseHL ps t