这个问题似乎与众所周知的mapreduce问题很接近,我认为应该以类似的方式解决它,将Map、Group和Reduce步骤分开。
让我们按照您的建议解决将 a 转换string
为有序列表的问题。int
let stringToInts (xs:string) =
/// The Mapper simply maps the character to its numeric value
let mapper = string >> Int32.Parse
/// The Grouper "concatenates" 'x' to the 'current' value
/// if the result is greater than the 'threshold', updates the
/// 'threshold' and drops the 'current'
/// otherwise, just updates the 'current'
let grouper (threshold, current) x =
let newCurrent = current*10 + x
if newCurrent > threshold
then newCurrent, 0
else threshold, newCurrent
/// The Reducer takes only the values with zero 'current' field
/// and unwraps the tuple
let reducer = function
| x, 0 -> Some x
| _ -> None
xs.ToCharArray() // get the chars
|> List.ofArray // convert to List
|> List.map mapper // **Map them to int values
|> List.scan grouper (97, 0) // **Group the values so that each one
// is greater than the threshold
|> List.choose reducer // **Reduce by zero 'current'
|> List.tail // skip the bootstrapper
"9899100101102103104105"
|> stringToInts
|> List.iter (printf "%O ")
// outputs:
// 98 99 100 101 102 103 104 105
可以将所有三个步骤包装成一个函数,但我真的认为没有实际理由这样做。