如果有一组线性增长且刚好在[0, 1]
内的数[0, 0.25, 0.5, 0.75, 1]
,那么不需要任何计算,这几个数就是均匀分布在0到1内的。假设x
从0递增到1,每次加0.01,任意时刻它的结果y∈[0, 1]
就等于x
。当x
走到0.25
时刚好在[0, 1]
的四分之一处,x
走到0.5
时刚好在二分之一处,任何人都可以直接看出来。其实这里也有个映射关系的,就是y=x * 1
,因为乘以1可以省略,所以看起来就是x
没做任何计算就均匀映射到[0, 1]
内了。这么简单的东西,实际上还是有点用的。
接着来看第二组数,也是线性增长,但不是在[0, 1]
范围内的[0, 2, 4, 6, 8]
,x
从0增到8,每次加0.1,那么任意时刻的x
映射到[0, 1]
的结果y
,就为y=x / 8
。也就是当x
走到2时刚好在y
的四分之一处,走到4时刚好在y
的二分之一处。因为x是线性增长的,所以要将[0, 8]
映射到[0, 1]
内,就是[0 / 8 = 0, 8 / 8 = 1]
。也就是将[0, 2, 4, 6, 8]
均匀映射到[0, 1]
的映射关系就是y=x / 8
,结合上面那一步,完整的映射关系应该是y=x / 8 * 1
。
说完了上面那两步,就可以回到标题说的那个问题上了。假设有一组非线性增长的数[0, 2, 3, 9, 14]
。线性增长的意思,可以看做:当前的数减去它前一个数,等于它后一个数减去当前的数。而这组数显然是不符合这条件的。如果还要将这组数均匀的映射到[0, 1]
内,也就是x
从0增到14,每次加0.1,当x
走到2时要刚好在[0, 1]
四份之一处,走到3时要在二分之一处,走到9时在四分之三处,走到14刚好就是1。那直接用第二步的方法的话,0除以14确实为0,14除以14也确实为1,但是3/14并不等于1/2,是无法达到效果的。当然解决办法还是有的,几行代码就可以搞定。当一个问题无法解决时,可以将其转化为已解决的问题,然后用已知的方法把未解决的问题给解决掉。[0, 2, 3, 9, 14]
无法直接映射到[0, 1]
,但是可以先把它转换成[0, 1, 2, 3, 4]
这样一组线性增长的数,将这组数映射到[0, 1]
内那不是简简单单,直接套用第二步的方法[0 / 4 = 0, 4 / 4 = 0]
得到映射关系就是y=x / 4
。那[0, 2, 3, 9, 14]
怎么转换成[0, 1, 2, 3, 4]
,其实也不难,通过观察,就可以得到:0、2、3、9、14在数组里的下标,就是0、1、2、3、4,也就是当x
走到2时,就可以得到1,走到3时得到2,当然这不是计算出来的,而是固定死的对应关系。但是还有一个问题,x
每次加0.1,某一时刻x
走到了1,那这个1怎么对应到[0, 1, 2, 3, 4]
内呢?还是通过观察,1在0-2的中间,也就是占了0.5,那0-1的0.5还是0.5,x
为2.1时在2-3之间占了0.1,那1-2的0.1就是1.1,总结成一般规律就是x - i / j - i