阅读烂代码

因为需要维护已有的程序,但是当时写的同事早已经离开了公司不得不阅读他写的代码。代码质量确实不敢恭维,随意使用的变量、string 与 int 之间随意转换、大量嵌套的 if else 、类似的代码上下重复一遍仅一两个变量不一样等等不一而足。于是阅读的时候心里不是很舒服,读起来确实难受。

为了理解其中的含义,写注释是一个好方法。写注释可以缓解那种立马大改特改的冲动,还可以帮助理解代码中的逻辑,并且可以使得心里舒服一点。好好多多。今天花了不少时间去写这种注释。在遇到一个新的项目,要求修复其中的问题时,不用一开始就着手去改,先写点注释,让 SVN 对比的压力也小一点,再在理解的基础上一部分一部分修改才是正确的方式。

周末的时候简单学习了一下 Python 和 PHP 语言,PHP 语言由于去年做过一点小东西,所以就比较简单看了一下。加上 Scala 、Lua、Javascript 三门语言就已经是五门函数式编程语言了。说实话函数式编程这种将函数看做变量的写法确实带来很大便利。此处贴出两段八皇后的问题管中窥豹。

Python 中尝试了两种解法,第一种是先递归解决后面的子问题再合并当前的答案,第二种是先递归解决前面的子问题再合并当前的答案。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def conflict(state, nextx):
    nexty = len(state)
    for i in range(nexty):
        #同一列或者在对角线上
        if abs(state[i] - nextx) in (0, nexty - i):
            return True
    return False

def queens_1(num=8, state=()):
    for pos in range(num):
        if not conflict(state, pos):
            if len(state) == num - 1:
                yield (pos,)
            else:
                for result in queens_1(num, state + (pos,)):
                    yield (pos,) + result

def queens_2(num=8):
    def place_queen(k):
        if k == 0:
            yield ()
        else:
            for state in place_queen(k-1):
                for pos in range(num):
                    if not conflict(state, pos):
                        yield state + (pos,)
    for ret in place_queen(num):
        yield ret

Scala 按照一样的方式尝试两种方法,可以从中稍微看出 Python 和 Scala 两种不同的函数式编程, Python 版本使用了生成器语义,而 Scala 中没有对应的概念。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def queens_1(n: Int): List[List[(Int, Int)]] = {
    def placeQueens(k: Int): List[List[(Int, Int)]] = {
      if (k == 0)
        List(List())
      else {
        for {
          queens <- placeQueens(k - 1)
          column <- 1 to n
          queen = (k, column)
          if isSafe(queen, queens)
        } yield queen :: queens
      }
    }

    placeQueens(n)
  }

  def queens_2(n: Int): List[List[(Int, Int)]] = {
    def placeQueens(queens: List[(Int, Int)]): List[List[(Int, Int)]] = {
      val k = queens.length + 1
      val ret = new ListBuffer[List[(Int, Int)]]

      for {
        column <- 1 to n
        queen = (k, column)
        if isSafe(queen, queens)
      } {
        if (k == n)
          ret += List(queen)
        else
          for (tailQueens <- placeQueens(queen :: queens))
            ret += (tailQueens :+ queen)
      }
      ret.toList
    }

    placeQueens(List())
  }

  def isSafe(queen: (Int, Int), queens: List[(Int, Int)]) =
    queens forall (q => !inCheck(q, queen))

  def inCheck(q1: (Int, Int), q2: (Int, Int)) =
    q1._1 == q2._1 || q1._2 == q2._2 || (q1._1 - q2._1).abs == (q1._2 - q2._2).abs