2013-11-02 30 views
0

我想定義一個函數,它接受一個整數n並返回一個整數n *,使得n和n *在1到n的整數集中,並且函數必須是雙射的。sml中的雙射函數

我嘗試以下

fun bij(n) = 
     let 
     val ls = zip(upto (1, n), List.rev(upto (1, n))) 
     val Tw_2 = fn(a, b) => b 
     in Tw_2(List.last(ls, n-1)) end; 

但不幸的是,它爲我的n的所有值返回1。我真的被困在這裏。 任何人都可以給我一些關於如何實現這個想法嗎?

bij行爲必須看起來像

bij(1) = 3 
bij(2) = 2 
bij(3) = 1 
+0

您是否可能想要定義一個函數,該函數需要一個整數n並返回一個函數,該函數需要一個整數m並返回一個整數m *,使得m和m *位於從1到n的相同整數集合中? – qaphla

+0

我不明白,在你的第一個例子中n = 1,n * = 3。那麼n和n *是如何在從1到n的整數集中呢?肯定n *應該是1到n之間的整數。你能不能請elaborare? –

+0

嗯,也許我沒有解釋我真正想要的,大圖像是這樣的:我有一個列表'[2,1,3]',我想要一個函數,將此列表重新排列爲'[1,2, 3]'例如。 – Emma

回答

1

如果我正確理解你的問題,一個簡單的解決辦法是:

fun bij(n, i) = n + 1 - i; 

這可以通過下表來表示

i   | 1 2 3 ... n-2 n-1 n 
bij(n, i) | n n-1 n-2 ... 3 2 1 

和哪些按預期工作的數字是吐溫1n。直接地,(正數)ii步驟「在0的右邊」,並且我們將其映射到i(實際上i - 1)步驟「在n的左邊」。

也許你想通過列表顯式構建上述表?

fun upto(m, n) = if n < m then [] else m :: upto(m+1, n); 

fun table n = ListPair.zip (upto(1, n), List.rev (upto(1, n))); 

例子:

> table 5; 
val it = [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]: (int * int) list 

然後拿到i個對列表xs的,你可以使用

List.nth (xs, i-1) 

把所有在一起

fun bij(n, i) = 
     let 
     val table = ListPair.zip (upto(1, n), List.rev (upto(1, n))); 
     fun snd(x, y) = y; 
     in snd(List.nth (table, i-1)) end; 

除了更復雜的方式外,它與初始函數的作用相同。