F# - 算法和字符串

时间:2017-08-08 21:24:07

标签: algorithm f#

假设我有一个长度为N且仅包含0或1的字符串。我想将该字符串拆分为多个字符串,每个字符串应只包含一个数字。

示例:

  

00011010111

应分为:

  
      
  • 000
  •   
  • 11
  •   
  • 0
  •   
  • 1
  •   
  • 0
  •   
  • 111
  •   

如果在字符串构建器中使用for循环,我可以想到的唯一解决方案(在下面的伪代码中编写,更多c#就像抱歉):

 result = new list<string>
 tmpChar = ""
 tmpString = ""
 for each character c in MyString
     if tmpchar != c
         if tmpsString != ""
             result.add tmpString
             tmpString = ""
         endIf
         tmpchar = c
     endIf
     tmpString += tmpChar
 endFor

您是否有任何其他解决方案,也许是一个使用功能更强大的方法的聪明解决方案?

4 个答案:

答案 0 :(得分:3)

我认为Seq.scan非常适合这种情况,这在本质上是一个非常程序性的问题,保留了这样的顺序。但是这里的代码我相信你做的是什么。

"00011010111"
|> Seq.scan (fun (s, i) x ->
    match s with
    | Some p when p = x -> Some x, i
    | _ -> Some x, i + 1 ) (None, 0)
|> Seq.countBy id
|> Seq.choose (function 
| (Some t, _), n -> Some(t, n)
| _ -> None )
|> Seq.toList

答案 1 :(得分:3)

也许有些事情如下:

let result = 
  let rec groupWhileSame xs result =
    match xs with 
    | a when a |> Seq.isEmpty -> result
    | _ -> 
      let head = xs |> Seq.head
      let str = xs |> Seq.takeWhile ((=) head)
      let rest = xs |> Seq.skipWhile ((=) head)
      groupWhileSame rest (Seq.append result [str])

  groupWhileSame (myStr) []

答案 2 :(得分:2)

Seq.fold (fun (acc:(string list)) x ->
          match acc with
          | y::rst when y.StartsWith(string x) -> (string x) + y::rst
          | _ -> (string x)::acc)
        []
        "00011010111"

答案 3 :(得分:0)

这是OP提案的可行版本,语法简单:

#!/bin/bash
echo 'cpp-options: -DCOMPILE_TIME_PATH="'$PATH'"' > my-package.buildinfo

未尝试遵循功能样式。