通过递增获取字母数字字符串的最佳方法

迪米特里斯梅尔

我正在为 F# 开发 Akka。我想按顺序生成字母数字字符串。

例如:第一个字符串是 0,第二个是 1,然后是 2,等等。当它达到 9 时,我想让它变成小写的“a”。当它到达“z”时,我希望它变成大写的“A”。当它到达“Z”时,它应该变成 00。等等......

我想按顺序搜索这些字符串的整个空间,我不想随机生成它们。基本上,我要求增加函数,例如i++,但不是以 10 为基数的算术,我希望它具有以 62 为基数的算术。在像 F# 这样的函数式语言中,最好的方法是什么?我可以以某种方式利用字母的 ASCII 表示是有序的这一事实吗?但随后数字与 ASCII 中的字母表示相邻。

额外问题:我怎样才能在这个系统上执行任何算术,让我们说x <- x+100

大卫·拉布

您基本上需要的只是一种将数字转换为字符串表示形式的方法,反之亦然。顺便说一下,这个任务对于每个基地都是一样的。这里有一个分步解决方案。

要将数字转换为二进制,您可以使用以下算法。

let rec toBinary x =
    if x = 0 then "0"
    else
        let y = x % 2
        (toBinary ((x-y)/2)) + (string y)

例如,这就是您转换为八进制表示的方式。

let rec toOctal x =
    if x = 0 then "0"
    else
        let y = x % 8
        (toOctal ((x-y)/8)) + (string y)

如你所见,它总是一样的。在底座上制作一个模块,以获得最正确的数字。重复基数的减法和除法。

20

20 % 2 = 0  // 20 / 2
10 % 2 = 0  // 10 / 2
5  % 2 = 1  // (5-1) / 2
2  % 2 = 0  // 2 / 1
1  % 2 = 1  // (1-1) / 2
         0      

这样,您可以从右到左使用数字,它适用于任何基数。

现在,您可以通过将基数作为数字来使其更通用,而不是编写每个版本。

let rec toBase nbase x =
    if x = 0 then "0"
    else
        let y = x % nbase
        (toBase nbase ((x-y)/nbase)) + (string y)

为了使其更加通用,您可以提供一个字符串列表,以及您的映射。像这样。

let rec toBase' nbase x =
    let bse = List.length nbase

    if x = 0 then 
        nbase.[0] 
    else
        let y = x % bse
        (toBase' nbase ((x-y)/bse)) + (nbase.[y])

现在,您可以创建任意映射。

let toBin  = toBase' ["0";"1"]
let toABCD = toBase' ["A";"B";"C";"D"]
let toHex  = toBase' ["0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"]
let toOct  = toBase' ["0";"1";"2";"3";"4";"5";"6";"7"]

接下来,你应该做相反的事情。映射一个字符串,返回一个数字。通常的方法是理解,一个数字是一个位置的乘法。例如,二进制数“1010”的真正含义是:

(1 * 8) + (0 * 4) + (1 * 2) + (0 * 1)

作为代码:

let rec toInt nbase x =
    let bse = List.length nbase
    let mut = pown bse (String.length x - 1)

    if x = "" then 
        0 
    else
        let fc    = string (x.[0])
        let index = List.findIndex (fun e -> e = fc) nbase
        (toInt nbase (x.[1..])) + (index * mut)

现在您可以定义反向。

let toBin   = toBase' ["0";"1"]
let fromBin = toInt   ["0";"1"]

let toABCD   = toBase' ["A";"B";"C";"D"]
let fromABCD = toInt   ["A";"B";"C";"D"]

let toHex   = toBase' ["0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"]
let fromHex = toInt   ["0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"]

let toOct   = toBase' ["0";"1";"2";"3";"4";"5";"6";"7"]
let fromOct = toInt   ["0";"1";"2";"3";"4";"5";"6";"7"]

如果你现在想要一个数字流,你可以 List.map 你的数字,或者从中创建一个序列。例如,二进制数流。这个序列就是你想要的“++”操作。一个计算所有变体的懒惰序列。

let binaryStream = Seq.initInfinite toBin

for x in Seq.take 10 binaryStream do
    printfn "%s" x

// Will print
// 0
// 01
// 010
// 011
// 0100
// 0101
// 0110
// 0111
// 01000
// 01001

将打印第一个,10 个二进制数。如果要将 + 100 添加到字符串,请先将其转换为数字,再转换为数字乘法,然后再将其转换回字符串。或提供您想要的那些功能。例如添加两个二进制字符串。

let addBin x y =
    toBin ((fromBin x) + (fromBin y))

addBin "1000" "1010"  // 8 + 10

现在你可以做你的base62了。例如,打印前 200 个字符串。

let toB62 = 
    toBase' (
        List.map string [0..9]
        @ List.map string ['a' .. 'z']
        @ List.map string ['A' .. 'Z'])

let fromB62 =
    toInt (
        List.map string [0..9]
        @ List.map string ['a' .. 'z']
        @ List.map string ['A' .. 'Z'])

let b62stream = Seq.initInfinite toB62

for x in Seq.take 200 b62stream do
    printfn "%s" x

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

递增字母数字字符串

如何在PHP中获取字符串中字母数字字符的长度?

Swift-从字符串中仅获取字母数字字符

从用户输入中获取字母数字字符串的安全方法?(没有preg_replace)

如何提取字母数字字符串

正则表达式获取字母数字字符串之间的非字母数字字符串

获取字母数字字符串中最后一个数字之后的文本

根据可用数字和字母列表验证三个字母数字字符串的最佳方法

如何仅从字符串中提取字母数字字符?(SQL Google BigQuery)

拆分字母数字字符串

生成字母数字字符串

从客户语音中提取字母数字字符串

从行 Batch Windows 7 中提取字母数字字符串

如何在R中的字母数字字符串中获取数字/字母索引模式?

Razor-如何获取字符串的n个数字字符?

通过数字部分对字母数字字符串进行排序的SQL

JS 通过结尾数字对字母数字字符串数组进行排序?

从Go中的Writer获取字符串的最佳方法

从JavaScript中的字母数字字符串获取数字值

如何通过从字母数字字符中采样来创建随机字符串?

如何使用grep获取字符串中的第n个数字字段?

在python中通过字母或对从字符串中获取所有组合的最佳方法

从删除所有非字母数字字符的字符串中获取列表

在 Python 中从具有非字母数字字符的字符串中获取文本

字母数字字符串末尾的javascript增量数字

javascript | 匹配字母数字或数字字符串

如何提取字符串末尾的非数字字符和数字字符?

向R中的字母数字字符串添加数字的有效方法

仅计算字符串中的字母数字字符