F# 子串指数

F# 子串指数,f#,substring,F#,Substring,我对F#很陌生。我编写了一个函数,返回目标中子字符串匹配的索引数组,它与我在C#中编写的方法类似 有没有一种更实用的方法来解决这个问题,并且可以不使用任何可变变量来解决这个问题 let SubStringIndices (haystack:string) (needle:string) = let mutable indices = System.Collections.Generic.List<int>() let mutable index = haystack.

我对F#很陌生。我编写了一个函数,返回目标中子字符串匹配的索引数组,它与我在C#中编写的方法类似

有没有一种更实用的方法来解决这个问题,并且可以不使用任何可变变量来解决这个问题

let SubStringIndices (haystack:string) (needle:string) =
    let mutable indices = System.Collections.Generic.List<int>()
    let mutable index = haystack.IndexOf(needle)
    while index >= 0 do
        indices.Add(index)
        index <- haystack.IndexOf(needle, index+1)
    indices.ToArray()

printfn "%A" (SubStringIndices  "abaabababaaab" "ab")
// prints [|0; 3; 5; 7; 11|]
let子字符串索引(草堆:字符串)(针:字符串)=
让可变索引=System.Collections.Generic.List()
让可变索引=haystack.IndexOf(针)
而索引>=0则
索引。添加(索引)

index这里有一个简单的递归函数,它做同样的事情:

let rec subStringIndices (haystack:string) (needle:string) (from:int) =
  let index = haystack.IndexOf(needle, from)
  if index >= 0 then 
    let rest = subStringIndices haystack needle (index + 1)
    index::rest
  else []

printfn "%A" (subStringIndices  "abaabababaaab" "ab" 0)
该函数从
中获取一个附加参数
,该参数表示起始索引(您要在字符串中开始搜索的位置)。最初,该值设置为零。在函数中,我们首先得到下一个索引。如果我们找到了什么,我们递归地处理字符串的其余部分(从
index+1
)并返回一个包含索引和所有递归获得的索引的列表

可以使用累加器参数技巧和嵌套函数编写使用尾部递归的稍微优雅和更高效的版本:

let subStringIndices (haystack:string) (needle:string) =
  let rec loop (from:int) acc =
    let index = haystack.IndexOf(needle, from)
    if index >= 0 then 
      loop (index + 1) (index::acc)
    else
      List.rev acc
  loop 0 []
递归循环现在由
循环
函数实现。它从外部获取
haystack
needle
作为参数,因此不需要在堆栈上复制这些参数。我们在作为参数传递的
acc
列表中累积索引,当我们到达末尾时,我们返回列表(相反,因为我们在前面添加了新项)。

类似于

let SubStringIndices (haystack:string) (needle:string) = 
    -1 |> Seq.unfold (fun n -> 
        let idx = haystack.IndexOf(needle, n + 1)
        if idx <> -1 then Some(idx, idx) else None        
        )
let子字符串索引(haystack:string)(针:string)=
-1 |>顺序展开(乐趣n->
设idx=haystack.IndexOf(针,n+1)
如果idx-1,那么一些(idx,idx)其他没有
)

但它不能正常工作,您没有使用match。。。任何地方都有!;)@Massif:-)递归应该足够好了!但是您可以使用
match
来测试
索引
(这不会使代码变得更好,所以我没有这样做)它应该是一些(idx,idx)。。unfold就是我要找的,thanksThanks,直接在browserBTW中键入时打错了,在本例中没有必要使
索引
可变。此集合类型本身是可变的。通过声明
index
mutable,可以创建对可变集合的可变引用。