【问题标题】:Encoding very large numbers into Strings将非常大的数字编码为字符串
【发布时间】:2015-10-14 22:26:15
【问题描述】:

我一直在尝试使用 PHP 将非常大的整数编码为大写字母序列。将 0 到 25 的值分配给 A~Z 我将 10 亿缩短到 DGEHTYM。如果实现了工作算法,使用不同的情况、数字甚至符号,则生成的字符串可能会短得多。然而,我的目标只是一串大写字母,也许还有数字字符以使其更短,但不是必须的。

使用笔、纸和我手机的计算器进行编码:

  • 找到26的最大幂,低于10亿(php有函数log)。 10 亿是 6。所以 26^6 = 308,915,776
  • 1,000,000,000 by 308,915,7763.237 有很多小数
  • 3D。我们收到了第一封信!
  • 现在我们将一遍又一遍地做同样的事情,直到我们得到一个整数:取出整个部分并将剩下的小数乘以 26。我们取出的每一个整体都是一封信。对于 10 亿,我循环了 6 次,直到得到 12 次,即 M

也许有更聪明的方法可以做到这一点,但我还没有想出来。

也许我应该采取不同的做法,但由于缺乏更好的方法,我尝试在 PHP 中复制我的计算,但我遇到了问题:1: 编码的数字很难编码会以 A (0) 结尾,例如 1326 这将是 BZA 和 2:我无法让 PHP 检测是否number 有或没有小数。我不得不不断地将它转换成一个字符串并寻找一个点。

解码字符串更容易。从从右到左,你将每个字母的值乘以 26 提升到它的位置的幂,除了第一个,它们相加:

D => 3 x (26^6) = 926,747,328
G => 6 x (26^5) = 71,288,256
E => 4 x (26^4) = 1,827,904
H => 3 x (26^3) = 123,032
T => 19 x (26^2) = 12,844
Y => 24 x 26 = 624
M => 12
926,747,328 + 71,288,256 + 1,827,904 + 123,032 + 12,844 + 624 + 12 = 1,000,000,000

有一个类似的问题here,但回答的人似乎不明白 OP 试图完成什么。

【问题讨论】:

  • 所以基本上,你想将一个很长的base10数字转换为base26,对吧?结果如何实现重要吗?
  • 是的。不,如何实现并不重要,只要结果只是大写字母即可。

标签: php math encoding logarithm


【解决方案1】:

您正在从基数 10 转换为 26,这是在 base_convertgmp_strval 等内置函数可以处理的范围内。他们会以 0-9 和 a-p 的形式给出数字,因此您只需使用 strtr 将它们转换成您想要的数字。

$translate = array_combine(
    array_merge(range(0, 9), range('a', 'p')),
    range('A', 'Z')
);

echo strtr(base_convert(1000000000, 10, 26), $translate), "\n";
echo strtr(base_convert(1326, 10, 26), $translate), "\n";

//Or if you're working with really big numbers (beyond PHP_INT_MAX):
echo strtr(gmp_strval(1000000000, 26), $translate), "\n";
echo strtr(gmp_strval(1326, 26), $translate);

输出:

DGEHTYM
BZA
DGEHTYM
BZA

或者手动进行,这样可以很容易地为不同的基础和编码添加/删除符号。基本上,您将输入的数字除以基数,使用余数查找该位置的适当符号,然后重复除法的结果。

function base10_to_whatevs($num, array $digits)
{
    $result = '';
    $base = count($digits);
    while ($num > 0) {
        $remainder = $num % $base;
        $num = ($num - $remainder) / $base;
        $result = $digits[$remainder] . $result;
    }
    return $result;
}

$letters = range('A', 'Z');
echo base10_to_whatevs(1000000000, $letters), "\n";
echo base10_to_whatevs(1326, $letters);
DGEHTYM
BZA

【讨论】:

  • 你写的函数正是我想要的。我不得不做一些谷歌搜索才能理解$num % $base 位。一旦我做到了,这一切都是有道理的。它证实了我的理论,即我使用 PHP 的方法不是最好的,并且有一种更有效的方法可以实现相同的结果。谢谢;-)
  • 如何将字母转换回原来的数字?
猜你喜欢
  • 2015-03-16
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
相关资源
最近更新 更多