我认为是一种编码系统。 arr[(encoded code)]=(decoded code)
如下:
arr
是一个二进制非负整数数组,小于2 ^ 16(pow(2,16))。
arr[0]=0
arr[1...16]
都有一个1.(1,10,100,1000 ......)arr[17...136]
中的每一个都有两个1。 (11,101,110,1001 ......)每个arr[137...696]
都有三个1。 (111,1011,1101,1110 ......)
... arr[(sum of 16C(n-1))...(sum of (16Cn))-1]
中的每个二进制文件都有n
1个。
arr[65519...65534]
都有15个1。arr[65535]
是2 ^ 16-1(1111 1111 1111 1111
)。我没有决定如何对每个部分进行排序,这并不重要。 (但是,部分应按1的数量排序。)合适的编码 - 解码算法将决定如何排序。 (例如,如果算法正常,则可以是arr[1]=4
,arr[2]=2
和arr[3]=8
。)
我想在不在此表中搜索的情况下编写函数和解码函数。任何好的解决方案&排序方法?
答案 0 :(得分:1)
让C(i, j)
为长度i
的二进制字符串计数,其中j
1
s。这是众所周知的选择函数,其计算方式为i! / (j! * (i-j)!)
。
让我们按如下方式对它们进行排序。首先是C(16, 0)
,没有1
。然后C(16, 1)
只有一个1
。然后C(16, 2)
有两个1
s,依此类推。在一个组中,我们按字典顺序排序。因此,在C(16, 2)
组中,我们将C(15, 2)
设置为两个尾随1
和一个前导0
,然后是C(15, 1)
,其中前导1
在某个地方跟踪1
。
现在给出一个二进制字符串,它们之前出现了什么?所有1
次C(16, 0) + C(16, 1) + ... + C(16, i-1)
的{{1}} i
,如果此1
个0
。然后对于字符串中的每个1
,我们知道有多少匹配到该位置,其中有1
,其余16
s。这是以前的一组。这些都是以前的那些,所以添加它们,我们知道这个位置。这个计算最多需要16个步骤,计数较少1
s,另一个最多f(16, 0)
个步骤对于二进制数中的f(16, 1)
s,最多32步。
另一种方式呢?我们首先继续减去1
,1
等,直到我们找出二进制数中必须有多少0
s。然后我们从左边开始,如果我们需要足够的数据,我们可以放入{{1}}并减去我们找到的组,或者是否应该有{{1}}这里。同样,这最多需要32个步骤。