Algorithm 将整数映射到给定字符串空间中的字符串

Algorithm 将整数映射到给定字符串空间中的字符串,algorithm,language-agnostic,Algorithm,Language Agnostic,假设我有一个字母表'abcd',最大字符串长度为3。这给了我,包括空字符串。我想做的是在不使用查找表的情况下,将[0,85]范围内的整数映射到字符串空间中的字符串 0 => '' 1 => 'a' ... 4 => 'd' 5 => 'aa' 6 => 'ab' ... 84 => 'ddd' 如果字符串是固定长度的,则使用此伪代码算法可以很简单地执行此操作: str = '' for i in 0..maxLen do str += alphabe

假设我有一个字母表'abcd',最大字符串长度为3。这给了我,包括空字符串。我想做的是在不使用查找表的情况下,将[0,85]范围内的整数映射到字符串空间中的字符串

0 => ''
1 => 'a'
...
4 => 'd'
5 => 'aa'
6 => 'ab'
...
84 => 'ddd'
如果字符串是固定长度的,则使用此伪代码算法可以很简单地执行此操作:

str = ''
for i in 0..maxLen do
    str += alphabet[i % alphabet.length]
    i /= alphabet.length
done

但是,当字符串的长度可能在[0,3]范围内的任何位置时,我无法找到一个好的、有效的方法。这将在一个紧密的循环中使用随机输入,因此我希望避免任何不必要的分支或查找。

计算每个长度的字符串数:N0、N1、N2和N3(实际上,您不需要N3)。然后,使用这些值对整数空间进行分区:0..N0-1为长度0,N0..N0+N1-1为长度1,等等。在每个分区内,您可以使用固定长度算法


在最坏的情况下,您已经大大减少了查找表的大小。

将索引移动1,并暂时忽略空字符串。因此,您将映射
0->“a”、…、83->“ddd”

那么映射就是

n -> base-4-encode(n - number of shorter strings)
有26个符号,这是Excel列编号方案

对于
s
符号,有
s+s^2+…+s^l
长度最多的非空字符串
l

因此,给定
n
,找到最大的
l
,使得
s*(s^l-1)/(s-1)0,'b'~>1,…)

对于包含空字符串的问题,请将0映射到空字符串,对于
n>0
encode
n-1
,如上所述。

这里是一个C解决方案:

    static string F(int x, int alphabetSize)
    {
        string ret = "";
        while (x > 0)
        {
            x--;
            ret = (char)('a' + (x % alphabetSize)) + ret;
            x /= alphabetSize;
        }

        return ret;
    }
如果您想进一步优化它,您可能想做一些事情来避免字符串连接。例如,您可以将结果存储到预先分配的char[]数组中。

在Haskell中

encode cs n = reverse $ encode' n where
  len = length cs
  encode' 0 = ""
  encode' n = (cs !! ((n-1) `mod` len)) : encode' ((n-1) `div` len)
检查:

*Main>map(编码“abcd”)[0..84][”、“a”、“b”、“c”、“d”、“aa”、“ab”、“ac”、“ad”、“ba”、“bb”、“bc”、“bd”、“ca”、“cb”、“cc”、“cd”、“da”、“db”、“dc”、“dd”、“aaa”、“aab”、“aac”、“aad”、“aba”、“abb”、“abc”、“abd”、“aca”、“acb”、“acc”、“acd”、“adb”、“adc”、“adb”、“add”、“adb”、“add”、“baa”、“bab”、“bac”、“bad”、“bad”、“bba”、“bba”、“bba”、“bba”、“bcb”、“bcb”、“bcc”、“bcc”、“bcc”、“bbd”、“bcd”、“bda”、“bdc”、“cab”、“cab”、“cac”,“cad”、“cba”、“cbb”、“cbc”、“cbd”、“cca”、“ccb”、“ccc”、“ccd”、“cda”、“cdb”、“cdc”、“daa”、“dab”、“dad”、“dba”、“dbb”、“dbc”、“dbd”、“dca”、“dcb”、“dcc”、“dcd”、“dda”、“ddb”、“ddc”、“ddd”]


你对所涉及的数学的掌握显然比我强得多,但这正是我想要的;它工作得非常好。非常感谢你的帮助。
encode cs n = reverse $ encode' n where
  len = length cs
  encode' 0 = ""
  encode' n = (cs !! ((n-1) `mod` len)) : encode' ((n-1) `div` len)