2012年11月26日

qsort for ocaml

摘要: 其实跟scheme很类似的表操作,实现起来也比较容易。1 let rec qsort cmp lst =2 match lst with3 | [] -> []4 | h::r ->5 let less = List.filter (fun i -> (cmp i h) < 0) r in6 let great = List.filter (fun i -> not ((cmp i h) < 0)) r in7 (qsort cmp less) @ ( h::(qsort cmp gre... 阅读全文

posted @ 2012-11-26 19:46 mathlover 阅读(162) 评论(0) 推荐(0) 编辑

2012年11月25日

filter in Ocaml

摘要: 1 let filter p l = 2 let rec filter_int g ll rr = 3 match ll with 4 | [] -> rr 5 | h::r -> if (g h) then filter_int g r (h::rr) else filter_int g r rr 6 in 7 let rec map_int g ll rr = 8 match ll with 9 | [] -> rr10 | h::r -> map_int ... 阅读全文

posted @ 2012-11-25 19:04 mathlover 阅读(205) 评论(0) 推荐(0) 编辑

gcd, map for ocaml

摘要: gcd 的代码如下let gcd a b = let rec gcd_int x y = let r = x mod y in if r = 0 then y else gcd_int y r in if b = 0 then a else gcd_int a b ;;map的简单实现为let rec map f = [] -> [] |h::l -> f h :: map f l ;;这个实现不是尾递归的,对于长表来说可能会栈溢出,尾递归的版本为let map f l = let reverse lst r = match lst with ... 阅读全文

posted @ 2012-11-25 11:03 mathlover 阅读(225) 评论(0) 推荐(0) 编辑

2012年11月24日

几个简单函数的实现,就当做是ocaml练习用的

摘要: 第一个函数式求和,从i到j求和,这里假定i是下限,j是上限let rec sum i j = if i > j then 0 else i + (sum (i+1) j) ;;这个递归实现很简单,但是由于不是尾递归的,所以编译器不能转成迭代来计算,当递归层数太高的情况下stack会溢出,稍微修改一下,可以改成递归版本let sum i j = let rec sum_int i j s = if i > j then s else sum_int (i+1) j (s+i) in sum_int i j 0 ;;这里定义了一个sum_int的内部函数,他是一个尾递归的函数,编译器会 阅读全文

posted @ 2012-11-24 19:58 mathlover 阅读(540) 评论(0) 推荐(0) 编辑

2012年10月29日

将一个整数划分为非负整数的部分

摘要: 比如,4=1+1+1+1=1+1+2=1+2+1=1+3=2+1+1=2+2=3+1=4总共有8种方法,一般的,证书n有2n-1种划分方法,可以设计一种方法,按照字典序将所有的划分方法都输出来。其中的思路为,给定一个n,使用一个长度为n的数组,初始化每个元素为1,每次将低位的元素分出一个元素出来,加到相邻的高位上面。 1 void part(int n, int* as, void (*fn)(int,int*)) 2 { 3 int j; 4 int i; 5 for(j=0;j<n;j++) 6 as[j]=1... 阅读全文

posted @ 2012-10-29 20:22 mathlover 阅读(232) 评论(0) 推荐(0) 编辑

2012年10月17日

子序列和最大的问题

摘要: 给定一个序列a1,a2,...,an,求子序列中和最大的那个。如果使用暴力算法,需要使用O(n2)的时间复杂度。使用动态规划可以将时间复杂度下降到O(n),具体方法如下:定义bi为以ai结尾的所有序列中最大值,显然max{b1,b2,b3,...,bn}就是子序列和的最大值,bi满足关系式b1=a1bi=max{bi-1+ai, ai}通过这个关系式,可以在O(n)的时间内把所有bi求出来,然后求最大值就可以了。注意到bi只有在求bi+1以及求最大值的时候才用到,我们也可以把这两个过程合并起来。维护一个当前子序列和最大值,如果bi比最大值还大,则更新最大值,这样数组bi实际上也不需要了。 阅读全文

posted @ 2012-10-17 18:07 mathlover 阅读(278) 评论(0) 推荐(0) 编辑

2012年10月15日

生成一个序列所有排列的算法

摘要: 递归算法比较简单vector<string> p(string s){ vector<string> result; if(s.size() == 1) { result.push_back(s); return result; } for(int i=0;i<s.size();i++) { char c=s[i]; string subs=s; subs.erase(i,1); vector<string> t=p(subs); for(int i=0;i<t.size();i++) result.push_back(t[i].append(1 阅读全文

posted @ 2012-10-15 13:46 mathlover 阅读(244) 评论(0) 推荐(0) 编辑

2012年10月2日

quick sort and insert sort

摘要: quick sort的思想是使用一个元素将表分成2个部分,其中一个部分是比改元素小,另外一部分是大于等于该元素。在scheme里面实现起来相当直观(define (qsort p lst) (if (null? lst) '() (let ((e (car lst)) (rest (cdr lst))) (let ((less (filter (lambda (x) (p x e)) rest)) (great (filter (lambda (x) (not (p x e))) rest))) (append (qsort p less) (cons e (qsort p great 阅读全文

posted @ 2012-10-02 22:25 mathlover 阅读(256) 评论(0) 推荐(0) 编辑

merge sort in scheme

摘要: merge sort的思想很简单,首先将表均匀分成2份,然后每份都是递归使用merge sort来排序,最后使用一个线性合并的方法来合并两个有序表。为此我们首先定义的是split-evenly,用来切分一个list(define (split-evenly lst) (if (null? lst) (list '() '()) ;空表的话返回两个空表 (let* ((h (car lst)) (rest (cdr lst)) (len (length lst)) (sp (split-evenly rest)) (first (car sp)) (second (cadr sp 阅读全文

posted @ 2012-10-02 22:20 mathlover 阅读(226) 评论(0) 推荐(0) 编辑

2012年9月29日

scheme中表只能操作头部带来的一个问题

摘要: 很多简单的算法,为了能够转成尾递归,不得不采取比较繁琐的计算过程,或者使用多遍的遍历过程。在scheme中,比如map的实现,按照定义的实现(define (map p l) (if (null? l) '() (cons (p (car l)) (map p (cdr l)))))是一个普通的递归,无法转成迭代进行计算。为了使用迭代的结构,必须首先定义一个list的反转过程,其定义为(define (reverse l) (define (reverse-iter r l) (if (null? l) r (reverse-iter (cons (car l) r) (cdr l)) 阅读全文

posted @ 2012-09-29 22:55 mathlover 阅读(332) 评论(0) 推荐(0) 编辑

导航