用一个整数表达一个序列,可能吗

引言

早年,我发现了一种可以用一个整数表示一个序列的数学方法。
下表是3个数字的全排列,有6种情况,编号0到5。

编号 序列
0 0,1,2
1 0,2,1
2 1,0,2
3 1,2,0
4 2,0,1
5 2,1,0


(图片来自网络)

编码

下面介绍如何从序列计算出编号。以2,1,3,0为例。

2 1 3 0   2+0*4=2
  1 2 0   1+2*3=7
    1 0   1+7*2=15
      0   0+15*1=15
  • 首先,取最左的数字2,得到了2。剩下1,3,0。把大于2的数字减1,得到1,2,0。
  • 其次,取最左的数字1,把上一步得到的2,乘以当前的数字个数3,再和1相加,得到7。剩下2,0,把大于1的数字减1,得到1,0。
  • 再次,取最左的数字1,把上一步得到的7,乘以当前的数字个数2,再和1相加,得到15。剩下0,把大于1的数字减1,得到0。
  • 最后,取最左的数字0,把上一步得到的15,乘以当前的数字个数1,再和0相中,得到15。
    序列有几个数字,就作几次运算。

用同样的算法,把0,1,2,3共4个数字的全排列24种序列进行计算,刚好得到0至23共24个整数。

解码

那么,如何反算编号,还原出序列呢?以15还原出0~3共4个整数为例。

                 0
15/2=7...1   1   1 0
7/3=2....1   1   1 2 0
2/4=0....2   2   2 1 3 0
  • 首先,固定给序列加上数字0。
  • 其次,当前序列的个数1加上固定1得到2。15除以2商7余1,把余数1加到序列的左边,得到1,0。
  • 再次,和上一步同样的算法,上一步的商7除以3商2余1,把序列中比1大的数字加1,再把1加到序列的左边,得到 1,2,0
  • 最后,和上一步同样的算法,上一步的商2除以4商0余2,把序列中比2大的数字加1,再把2加到序列的左边,得到 2,1,3,0
    要还原的序列有几个数字,就作几次运算。最后一次运算的商肯定是0。

用同样的算法,把0至23共24个数字进行计算,刚好得到全排列24种序列。

优点

这种算法有什么优点

  1. 一个整数,就能存储一个序列,非常节约了存储空间。
    多个数字变一个
  2. 不同的序列,换算成的整数是连续的,还是节约存储空间。
    这一个数字还很小
  3. 支持任意个数字的序列,有普通性。
    上述的例子是4个数的序列,这种算法支持任意的个数。当然,不能少于1个。

限制

这种算法有什么限制

  1. 整数必须是从0开始,并且是连续的,即是0~n,共n+1个数。不是这种情况,得先转化成这种情况。
  2. 必须是整数,不支持字符,除非能换算成整数

数字的个数

前面的例子,要还原出序列,即需要数字15,也需要知道序列的个数,即数字4。所以,完整来讲不是一个数,而是两个数。
在很多场景下,序列的个数是事先约好的,是固定的,所以,又变成了一个数。

看待

在我看来,这是一种从0开始的,顺序的,不重复的,整数序列的极致压缩算法

由来

记得在2010年,就向朋友介绍过这种算法。这位朋友长期在国外,最近回国可能是探亲。令我想起这种算法,所以编理成文。
这种算法不是在哪里抄的,或借鉴的,是我自个儿琢磨的。目前推算,应该是2005至2010之间想出来的。

posted @ 2023-12-29 09:06  BillySir  阅读(100)  评论(0编辑  收藏  举报