生成Incresing序列的数学公式

时间:2016-10-04 21:11:52

标签: algorithm math

我有两个查询表,如果可能的话,我想用简单的数学来消除。

第一个是从数组中的索引到序列{0} =>的映射。 1,{1,2} => 2,{3,4,5} => 3,s.t。有一个,两个2s,三个3s等。或者视觉上:

lookup1[N] = { 
    1,
    2, 2,
    3, 3, 3,
    4, 4, 4, 4,
    5, 5, 5, 5, 5,
    6, 6, 6, 6, 6, 6,
    7, 7, 7, 7, 7, 7, 7,
    8, 8, 8, 8, 8, 8, 8, 8,
    ...
}

第二个是增加序列,第一个序列是(1),第二个(1,2),第三个(1,2,3)。它类似于模数周期,但在每个周期后增加。目测:

lookup2[N] = {
    1,
    1, 2,
    1, 2, 3,
    1, 2, 3, 4,
    1, 2, 3, 4, 5,
    1, 2, 3, 4, 5, 6,
    1, 2, 3, 4, 5, 6, 7,
    1, 2, 3, 4, 5, 6, 7, 8,
    1, 2, 3, 4, 5, 6, 7, 8, 9,
    ...
}

这些需要从索引进行映射。对于第二次查找,输入5,4,3将分别映射到3,2,1。

是否有任何数学公式可以产生这些模式?我宁愿执行一些指令而不是内存访问。

1 个答案:

答案 0 :(得分:3)

对于lookup1,这看起来与Triangular numbers密切相关,实际上它是反问题。三角形数字是具有n行的三角形中的项目数。所以你有T1 = 1,T2 = 1 + 2 = 3,T3 = 1 + 2 + 3 = 6,T4 = 1 + 2 + 3 + 4 = 10.或者作为函数f(1)= 1,f( 2)= 3,f(3)= 6,f(4)= 10.

你想做倒数,所以g(1)= 1,g(3)= 2,g(6)= 3,g(10)= 4.我们稍后会担心其他值。

有一个三角数f(n)= n(n + 1)/ 2的公式。一个更复杂的公式用于逆

g(n) = (sqrt(8 * n + 1) - 1) / 2 

一个小实验表明

ceil((sqrt(8*n+1) - 1) / 2 )

给出你想要的数字。

对于第二部分,您可以使用反三角数函数,然后找到前一个三角数,并取差值

X =  ceil((sqrt(8*n+1) - 1) / 2);
T = (X * (X-1))/2 ; 
print(n-T); 

轻微的警示。在转换点sqrt(8*n+1)应评估为奇整数值。对于非常大的n可能会发生的事情比舍入错误可能会产生影响。我已经测试了这个超过一百万,并且没有看到问题发生。