理解过程抽象 - webdancer's Blog

理解过程抽象

webdancer posted @ 2012年10月14日 01:48 in 编程语言 with tags 编程技术 , 1436 阅读

在学习编程的过程中,一个核心的任务是编写可以完成我们任务的函数。不管我们使用的什么语言,做什么开发,函数抽象并不少见。所谓的函数,我认为就是一些语句的集合,完成一个特定的任务。有了函数,我们思维时的操作原子型的层次变的比较高,思维的难度就会降低。但是在不同的编程实践中,为了完成任务需要的编写函数的思维方式也许是不同的,这会受到编程语言或是第三方库的影响。

在面向对象编程中,想得是如何构建类以及如何设计类之间的关系,充分利用对象的特性,例如在使用Java编程中,会想着如何设计Class,使用什么样的设计模式,这时候函数抽象的层次依赖与我们的类设计。在使用C这样的编程语言时,使用面向对象的设计,还是直接使用函数用来模块化,也会带来不同的设计函数的思维方式。使用像Lisp这样的函数式编程语言时,我们的思维与过程式的编程语言的方式可能会有很大的不同,函数就处于核心地位了。编程的思维可能会受到我们学习过的很多东西的影响,正如上面我陈述的。我的经验是学会抽象和使用语言提供的高层抽象,这样会大大的减低我们抽象函数的难度,使我们的注意力集中到解决我们的问题。通过自己的抽象和语言提供的高层抽象来实现层次化。
 
下面我使用不同的编程语言实现了冒泡排序,体会一下编程语言对我们思维的影响。
对冒泡排序,我还是比较熟悉的。算法的基本思想就是:两个指针i,j,i控制每次冒泡一遍的bubble的位置,j控制每一边冒泡时要比较的数的位置,两次循环就行了。
 
C语言实现
#include<stdio.h>

    void swap_int(int * a, int * b){
        int tmp=0;
        tmp=*a;
        *a=*b;
        *b=tmp;
    }

    void bubblesort(int * a,int n){
        int i;
        int j;
        for(i=0;i<n-1;i++){
            for(j=n-1;j>i;j--){
                if (a[j]<a[j-1]){
                    swap_int(&a[j],&a[j-1]);
                }
            }
        }
    }
在写这段代码时,我饭的错误就是给`swap_int`传递实参的时候没有取地址,这就是我对`C`语言的思维的盲区,对于`a[j]`与`a+j`我没有他们不同的认识。
 
python实现
    def bubblesort(l):
        n=len(l)
        for i in range(n-1):
            for j in range(n-1,i,-1):
                if l[j]<l[j-1]:
                    l[j],l[j-1]=l[j-1],l[j]
显然`python`要比C短的多,但这不代表我没有出错,因为有一段时间没写代码了,所以对`range(a,b)`的区间表示方式到底用了`[a,b]`还是`[a,b)`已经有点模糊不清了,所以就出了错。当然这种基本的问题,我们应该很明确的,但是尽管如此,我还是出错了。
 
java实现
    public class BubbleSort{

        public static void sort(int[] l){
            int n=l.length;
            for(int i=0;i<n;i++){
                for(int j=n-1;j>i;j--){
                    if(l[j]<l[j-1]){
                        swap_int(l,j,j-1);
                    }
                }
            }
        }

        private static void swap_int(int[] l,int m,int n){
            int tmp=l[m];
            l[m]=l[n];
            l[n]=tmp;
        }
    }
尽管`java`代码已经很久没写了,但是`java`与`c`的过程太相似了,基本没有费功夫,这里就是感觉java只有传值的参数传递方式的原因,`swap`函数一点也不优雅。
 
scheme实现
    (define (bubblesort l)
     (let ((n (vector-length l)))
     (map (lambda (i)
           (map (lambda (j) 
                 (if (< (vector-ref l j) (vector-ref l (- j 1)))
                  (swap l j (- j 1))))
            (range (- n 1) i -1)))
           (range 0 n 1))))

    (define (swap l a b)
     (let ((tmp (vector-ref l a)))
      (vector-set! l a (vector-ref l b))
      (vector-set! l b tmp)))

    (define (range low high step)
     (if (or (and (> step 0) (> low (- high 1))) (and (< step 0) (< low (+ high 1))))
      ()
      (cons low (range (+ low step) high step))))

    (define l (vector 2 3 1 5 4 7 8 9 1))
    (bubblesort l)
    (display l)
写`scheme`代码,因为最近在看`SICP`,所以代码的错误只是笔误,变量名写错这样的原因,可是我还是没能使用函数式的编程方式来写这段代码,主要就是函数式编程就要使用辅助的空间,所以使用了赋值操作。
 
从上面的过程中我有这么几个总结:
  1. 过程抽象对于我们解决问题,非常有用。使用高级语言提供的机制,可以大大解放我们的编程效率。
  2. 理解问题的时候,通常没法子一下理解的很好,所以在对问题的理解上,要多花功夫。
  3. 在写过程式的语言时,对于一些地方很模糊,这就是我们训练的地方。
  4. 函数式的编程方式,对思维的训练量很大。
思维是一个逐渐完善的过程,我们不能期望它一下子满足期待,要循序渐进的推进。要不断的训练,并且反馈,也许我们才会有一个比较好的抽象函数的能力,不管是面向对象编程还是函数式编程。

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee