2013-11-02 32 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; 

除了更复杂的方式外,它与初始函数的作用相同。