能不能設計針對確定數對的通用轉換函數?
給你N個數對,形式為&、&、……、&,能不能設計一個轉換函數r=transform(c),專門針對這N個數對的,其中c是數對左邊的值,r是右邊的值 。
注意這些數對是沒有任何規律的,唯一確定的是所有數對的值都在0~255之間,數對個數在10個以內。簡單舉個例子如下:給你四個數對:2, 4
5, 67, 187128, 253設計一個轉換函數,使得4=transform(2),6=transform(5),187=transform(7),253=transform(128),不知道能不能利用數學表達式設計出這樣的一個transform函數,謝謝。-------------------------------------------------------------------------更新:如果要求r=transform(c)的同時也要求c=transform(r)呢?也就是說是個對稱函數
插個值就好了,比如三個點的時候,
這就是所謂的拉格朗日多項式插值。
很容易推廣, n個點就有n項,第項使得在時候為,取其他時候為0。
簡單構造一下就可以了。
如果你認為下面的也是數學式子也行,C/C++可以,其他語言不確定(x==x1)*y1 + (x==x2)*y2 + (x==x3)*y3
四個點就是一條三次曲線嘛,你假設transform(x)=ax3+bx2+cx+d,然後帶進去得到四條方程,就可以求解了。如果求解的過程中你發現這其實不是一個三次方程而是一個二次方程或者更低(表現為他有很多解),那你就把高次項去掉,或者隨便挑一個解就可以了。
搞點線性代數就可以改定N&>=2為任意數的情況。
=====================================
如果要滿足f(f(x)) == x的話,把4個數據反過來就變成8個數據了,剩下的一樣。
定義在有限集上的函數,如果數不多的話,直接用hash表一對一映射好了 囧
數學上@程序猴子 的答案可以實現,但在編程時這樣需要O(n)時間,而且可能出現溢出問題。因為問題無須處理兩點中間的情況,插值並無必要。在編程時,可用Perfect hash function生成不會衝突的映射函數,達至完美的O(1)。實際上,一般的靜態語言的switch-case在編譯時已應用perfect hash,所以可以讓編譯器代勞:
uint8_t transform(uint8_t c) {
switch (c) {
case 2: return 4;
case 5: return 6;
case 7: return 187;
case 128: return 253;
}
return 0; // or other handling
}
如果是動態的,就要考慮計算perfect hash function還是用一般的hash。
當然,在題目這麼局限的數值範圍下,可以簡單用數組做映射,消耗一點內存:uint8_t m[256] = { 0 };
m[2] = 4;
m[5] = 6;
m[7] = 187;
m[128] = 253;
uint8_t transform(uint8_t c) { return m[c]; }
-----
更新:再加一個計算上可能較插值簡單的「數學表達式」,無須插值:拉格朗日插值法,牛頓插值法之類的方法就是來解決將離散的數據光滑連續地串在一起,並且給出一個穿過所有點的多項式表達式這樣的問題。
具體思路怎麼來的 @vczh 已經說了就不贅述了,下面是具體的過程。【數值分析】插值法:拉格朗日插值、牛頓插值不過既然都插值了為什麼不直接建立一個映射表,另外不是所有函數都可以用解析式表示出來的(遁..std::map&
想出用插值的我真是給跪了 時間空間精度沒一個好的 還不如if語句或者打表離散函數就不是函數了?
打表
推薦閱讀:
※Passphrase,Passcode,Password 三者之間有什麼區別和聯繫?
※長得漂亮的女程序員,如何在逛街時,讓別人覺得自己的職業是程序員呢?
※學習python有哪些好書和學習方法?
※編程在測繪工作的作用?
※什麼是編程的基本功?