2016-10-04 148 views
1

我有兩個查找表,如果可能的話,我想用簡單的數學來消除這兩個查找表。用於生成記錄序列的數學公式

第一個是從數組中的索引到序列{0} => 1,{1,2} => 2,{3,4,5} => 3,s.t.的映射。有一個1中,兩個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。

是否有任何數學公式會產生這些模式?我寧願執行一些指令,而不是執行內存訪問。

回答

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。 (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可能會發生什麼,而舍入錯誤可能會支付一部分。我已經測試了超過一百萬,並沒有看到問題發生。