F# - 十六进制转ASCII

3
  1. 以下代码中,有比Convert更好的方法来完成这两个操作吗?
  2. 我想知道这个解决方案(sprintf)是否比使用Substring更好(或更糟)
  3. 我想知道在这里使用list是否更好
  4. 前两个问题是否会因字符串大小而改变?(一个短字符串(小于20个字符)或一个长字符串)

假设输入总是正确的(没有奇怪长度)。

let hexToAscii (hex:string) =         
    let chars = Array.zeroCreate<char> (hex.Length/2)
    for i in 1..2..hex.Length-1 do
        chars.[i/2] <- Convert.ToChar(Convert.ToByte(sprintf "%c%c" hex.[i-1] hex.[i] , 16))

    String(chars)

这样的问题是否更适合提交到https://codereview.stackexchange.com进行?

1个回答

4
更符合惯用语的解决方案是这样的:
首先处理单个字节,例如“42”。
let hexByteToAscii (s:string) =
    System.Convert.ToByte(s,16)
    |> System.Convert.ToChar

并且让我们编写一个帮助函数,将字符数组转换为字符串。

let charsToString (chars:char[]) =
    new string (chars)

接下来,我们处理一个更长的序列,例如“4142”,通过使用2个字符的块并使用现有函数处理字节。

let hexToAscii (value:string) =
    value
    |>Seq.chunkBySize 2
    |>Seq.map ( hexByteToAscii << charsToString)
    |>Seq.toArray
    |>charsToString 

你可以进行测试:
hexToAscii "4142" // "AB"

从性能方面来说,两者的渐进时间复杂度都是O(n),其中n是输入字符串的大小。 除非你的n>10000(这似乎不是你的情况),否则不必过多担心。也许通过使用字典表实现自己的十六进制字节转ASCII函数可以获得一些收益。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接