F#计算子字符串包含在字符串中的次数

时间:2016-11-02 16:36:18

标签: string count f# contains

如何计算字符串中子字符串存在的次数?

我的意思是,如果你有一个字符串“one, two, three, one, one, two"你怎么能算出”一个“出现3次?

我认为String.Contains能够完成这项工作,但只检查子串是否存在。 String.forall用于表示,而且只有一个选项。

所以我真的完全停下来了。有人能帮助我吗?

5 个答案:

答案 0 :(得分:3)

您可以使用Regex.Escape将您要搜索的字符串转换为正则表达式,然后使用正则表达式函数:

open System.Text.RegularExpressions

let countMatches wordToMatch (input : string) =
    Regex.Matches(input, Regex.Escape wordToMatch).Count

测试:

countMatches "one" "one, two, three, one, one, two"
// Output: 3

答案 1 :(得分:2)

这是一个简单的实现,遍历字符串,使用String.IndexOf跳过下一个子字符串,并计算它成功的次数。

let substringCount (needle : string) (haystack : string) =
    let rec loop count (index : int) =
        if index >= String.length haystack then count
        else
            match haystack.IndexOf(needle, index) with
            | -1 -> count
            | idx -> loop (count + 1) (idx + 1)
    if String.length needle = 0 then 0 else loop 0 0

请记住,这会计算重叠事件,例如subtringCount "aa" "aaaa" = 3。如果您想要不重叠,只需将idx + 1替换为idx + String.length needle

答案 2 :(得分:1)

创建要搜索的字符串尾部序列,即在其末尾锚定的所有子字符串切片。然后,您可以使用forall功能来确定每个匹配项开头的匹配数​​。它比(fun s -> s.StartsWith needle)更高尔夫球。

let count needle haystack =
    [ for i in 0..String.length haystack - 1 -> haystack.[i..] ]
    |> Seq.filter (Seq.forall2 (=) needle)
    |> Seq.length

count "aba" "abacababac"
// val it : int = 3

答案 3 :(得分:0)

我的一位同学想出了我见过的迄今为止最简单的解决方案。

let countNeedle (haystack :string) (needle : string) =
      match needle with
      | "" -> 0
      | _ -> (haystack.Length - haystack.Replace(needle, "").Length) / needle.Length

答案 4 :(得分:0)

// This approach assumes the data is comma-delimited.
let data = "one, two, three, one, one, two"
let dataArray = data.Split([|','|]) |> Array.map (fun x -> x.Trim())
let countSubstrings searchTerm = dataArray |> Array.filter (fun x -> x = searchTerm) |> Array.length
let countOnes = countSubstrings "one"

let data' = "onetwothreeoneonetwoababa"

// This recursive approach makes no assumptions about a delimiter,
// and it will count overlapping occurrences (e.g., "aba" twice in "ababa").
// This is similar to Jake Lishman's answer.
let rec countSubstringFromI s i what = 
    let len = String.length what
    if i + len - 1 >= String.length s then 0
    else (if s.Substring(i, len) = what then 1 else 0) + countSubstringFromI s (i + 1) what

let countSubStrings' = countSubstringFromI data' 0 "one"