定制Vim

本文仅限Windows平台。无非就是一些个人的使用偏好,以及管理plugin的习惯。

1. 修改_vimrc,添加:

set number
set hlsearch
set enc=utf-8
set laststatus=2
set tabstop=4 shiftwidth=4 smarttab expandtab softtabstop=4 autoindent
set noswapfile

" for plugins: winmanager, taglist
let g:winManagerWindowLayout='FileExplorer|TagList'
nmap <F4> :WMToggle<CR>

" for plugin: mru
let MRU_Max_Entries = 20
let MRU_Add_Menu = 1

nmap <F2> :tabe<SPACE>
nmap <F3> :tabe<SPACE>^R%
nmap <C-Tab> :tabnext<CR>
nmap <C-S-Tab> :tabprev<CR>
nmap <F5> @Q
nmap <F6> @W
nmap <F7> @E
nmap <F8> @R
nmap <F9> @U
nmap <F10> @I
nmap <F11> @O
nmap <F12> @P

language en
source $VIMRUNTIME/delmenu.vim  
source $VIMRUNTIME/menu.vim  

highlight Normal guibg=lightyellow

(要输入^R,在insert模式下,如果是windows就^Q^R, Linux^V^R)

source那两行是在中文Windows下防止菜单乱码的。好像有个办法能防止工具栏提示乱码,懒得查了。

另外Vim对文件的编码还是需要研究一下的。

2. :source上面的_vimrc。下载最新的getscript插件:http://www.vim.org/scripts/script.php?script_id=642,Vimball安装之(用Vim打开getscript.vba,执行:so %)。其实本插件是标准插件,已经内置。这里只是搞个最新的。这个插件需要wget。

3. 重启Vim。编辑$VIM/vimfiles/GetLatest/GetLatestVimScripts.dist,同目录下另存为GetLatestVimScripts.dat,添加更多插件,然后:GLVS。这是我这儿更新后的:

ScriptID SourceID Filename
--------------------------
#294  1 Align.vim
#302  2 AnsiEsc.vim
#122  3 astronaut.vim
#104  4 blockhl.vim
#120  5 decho.vim
# 40  6 DrawIt.tar.gz
#451  7 EasyAccents.vim
#195  8 engspchk.vim
642 8136 GetLatestVimScripts.vim
#489 10 Manpageview.vim
#551 11 Mines.vim
#514 12 mrswin.vim
#670 13 visincr.vim
#628 14 SeeTab.vim
#508 15 ZoomWin.vim
#877 16 gvcolor.vim
1502 8743 vimball.tar.gz
42 9524 bufexplorer.vim
273 7701 taglist.vim
95 754 winmanager.vim
521 9274 mru.vim
2174 8373 repmo.vim

642 8136 :AutoInstall: getscript.vim
1502 8743 :AutoInstall: vimball.vim

注意ScriptID一定要像我这样写,SourceID则要写1。

其中taglist插件需要ctags。

我正在研究其他的一些插件,尤其是Python的。ptags.py很值得关注啊。不过现在的ctags已经支持n多种语言了。

4. 将down下来但没自动安装的插件(在$VIM/vimfiles/GetLatest下)安装到$VIM/vimfiles下。然后Vim里:helptags $VIM/vimfiles/doc来安装帮助文档。

大奥

这是个很简单的故事,本是后宫的势力斗争,却让一个处在阴谋中心处,本不谙情事的女人收获了一份真诚的爱情。是个悲剧,但哀伤却被那份真挚冲淡了很多。结局符合日本审美观,但相信其他文化背景的观众也都能很好的接受。

女主角仲间由纪惠是那种很大方的美丽,眼睛会说话。剧中随处可见日本传统服饰和让人心旷神怡的自然风光,看了很舒服。剧中的后宫女人都很寂寞很可怜,一方面她们处处勾心斗角,举手投足之间就能决定天下走势;另一方面她们也是普通的女人,这一点在影片最后,天英院看了空空如也的箱子不支倒地那一幕,得到了充分的体现。这一幕和之后绘岛满足的表情形成了很强烈的对比。前者赢得了权力斗争,后者赢得了爱情。我们更羡慕谁呢?

SICP-2.43 solution

就像前边说的,将map和flatmap视为循环。仔细观察两个版本的差别。

Louis Reasoner版本:

(flatmap
 (lambda (new-row)
   (map (lambda (rest-of-queens)
          (adjoin-position new-row k rest-of-queens))
        (queen-cols (- k 1))))
 (enumerate-interval 1 board-size))

此版本执行一次(enumerate-interval 1 board-size),之后外层循环board-size次;
外层每循环一次,就重新计算了一次(queen-cols (- k 1)),内层循环x次,x为计算到k-1列时,中间结果的数量。

原始版本:

(flatmap
  (lambda (rest-of-queens)
    (map (lambda (new-row)
           (adjoin-position new-row k rest-of-queens))
         (enumerate-interval 1 board-size)))
  (queen-cols (- k 1)))

此版本执行一次(queen-cols (- k 1)),
之后外层循环x次,x为计算到k-1列时,中间结果的数量;
外层每循环一次,就重新计算了一次(enumerate-interval 1 board-size),内层循环board-size次。

显然慢就慢在queen-cols被循环多次递归执行上面。
其实重复执行enumerate-interval也是资源浪费,但相对于递归执行的queen-cols来说其代价很小所以可以忽略。

接下来分析到底慢了多少。。。我最不会干这个。

对于原始版本,看这个
(define (queens board-size)
  (define (queen-cols k)
    (if (= k 0)
      ; if the board size is 0, return empty set of positions
      (list empty-board)
      ; if not
      (filter
        ; filter with a predicate which determines
        ; if the queen in kth column is checked from (former) positions
        (lambda (positions) (safe? k positions))
        (flatmap
          (lambda (rest-of-queens)
            (map (lambda (new-row)
                   (adjoin-position new-row k rest-of-queens))
                 (enumerate-interval 1 board-size)))
          (queen-cols (- k 1))))))
  (queen-cols board-size))
问题规模即board-size增加1,就多执行了一次queen-cols,(当然adjoin-position也多执行了但我们没考虑)所以是线性O(n)。

Louis版,
(define (queens board-size)
  (define (queen-cols k)
    (if (= k 0)
      ; if the board size is 0, return empty set of positions
      (list empty-board)
      ; if not
      (filter
        ; filter with a predicate which determines
        ; if the queen in kth column is checked from (former) positions
        (lambda (positions) (safe? k positions))
        (flatmap
         (lambda (new-row)
           (map (lambda (rest-of-queens)
                  (adjoin-position new-row k rest-of-queens))
                (queen-cols (- k 1))))
         (enumerate-interval 1 board-size)))))
  (queen-cols board-size))
(queen-cols k)调用board-size次(queen-cols (- k 1))。
问题规模为n时,(queen-cols n)调用n次(queen-cols (- n 1)),(queen-cols (- n 1))调用n次(queen-cols (- n 2))...因此共调用n^n次
啊,无敌了这不明摆着是O(n^n)嘛,我老潘果然神机妙算~

如果原版本是T,新版本就是n^(n-1)*T。

SICP-2.42 solution

; the board is represented as a list of lists, of course
;  
;   x 1 2 3 4 5 6 7 8
; y -------------------
; 1 | 0 0 0 0 0 x 0 0 |
; 2 | 0 0 x 0 0 0 0 0 |
; 3 | x 0 0 0 0 0 0 0 |
; 4 | 0 0 0 0 0 0 x 0 |
; 5 | 0 0 0 0 x 0 0 0 |
; 6 | 0 0 0 0 0 0 0 x |
; 7 | 0 x 0 0 0 0 0 0 |
; 8 | 0 0 0 x 0 0 0 0 |
;   -------------------
;
; Such a solution is represented as (from the left-most column):
; (3 7 2 8 5 1 4 6)
; So the intermediate result with k columns is represented as:
; (y1 y2 y3 ... yk)
;
; Note that this is only one way but definitely not the only way to represent
; the solution.
;
; Actually think about this:
; We go through the board from one side to the other side by
; recursion, say from left to right. We got to represent the intermediate/final
; result by a list simply because a pair is not enough.
; Ok then we have a list. We can use "append" to put the latest column at the
; rear (as we did already), or we can be cooler, using 'car' to put it at the head.

(define (enumerate-interval lower upper)
  (if (> lower upper)
      ()
      (append (list lower) (enumerate-interval (+ 1 lower) upper))))

(define (accumulate op initial sequence)
  (if (null? sequence)
    initial
    (op (car sequence)
        (accumulate op initial (cdr sequence)))))

(define (flatmap proc seq)
  (accumulate append null (map proc seq)))

(define (queens board-size)
  (define (queen-cols k)
    (if (= k 0)
      ; if the board size is 0, return empty set of positions
      (list empty-board)
      ; if not
      (filter
        ; filter with a predicate which determines
        ; if the queen in kth column is checked from (former) positions
        (lambda (positions) (safe? k positions))
        (flatmap
          (lambda (rest-of-queens)
            (map (lambda (new-row)
                   (adjoin-position new-row k rest-of-queens))
                 (enumerate-interval 1 board-size)))
          (queen-cols (- k 1))))))
  (queen-cols board-size))

(define (adjoin-position new-row k rest-of-queens)
  (append rest-of-queens (list new-row)))

(define empty-board ())

(define (safe? k positions)
  ; new position's y coordinate cannot be the same as any previous positions'
  ; and it cannot be in the diagonal of any previous positions
  (let ((new-position-y (list-ref positions (- k 1))))
    ; this procedure iterates thru 'positions'
    ; and sees if the latest position is checked
    (define (if-checked? positions column)
      (let ((position-being-checked-y (car positions)))
        ; if there is no previous positions, it's ok
        (cond ((empty? positions) #t)
              ; if we found ourserves checking the last element,
              ; which is the kth position, it's ok
              ((= k column) #t)
              ; if the new position's y coordinate equals to any previous positions'
              ((and (= position-being-checked-y new-position-y) (not (= k column))) #f)
              ; or the new position is in the diagonal
              ; of any previous positions, it's NOT ok
              ((or
                 (= position-being-checked-y (+ new-position-y (- k column)))
                 (= position-being-checked-y (- new-position-y (- k column)))) #f)
              (else (if-checked? (cdr positions) (+ column 1))))))
    (if-checked? positions 1)))

(define (print-queens queens)
  (let ((board-size (length queens)))
    ; print the correct board from the transposed board
    (define (iter transposed-board index)
      (if (= index board-size)
        ; for a board with size 8, the index is from 0 to 7
        ; if it's over
        (void)
        ; if not
        (void
          (for-each
            (lambda (x) (display (list-ref x index)) (display " "))
            transposed-board)
          (newline)
          (iter transposed-board (+ index 1)))))
    (iter
      ; the map expression is evaluated to a transposed board
      (map
        (lambda (y)
          (define (make-list result n)
            (if (= n 0)
              result
              (make-list (append result (list 0)) (- n 1))))
          ; append (y - 1) '0'
          ; append 'x'
          ; append (board-size - y) '0'
          (append (make-list () (- y 1)) (list 'x) (make-list () (- board-size y))))
          queens)
      ; index starts from 0
      0)))

(map (lambda (x) (print-queens x) (display "---------------") (newline))
     (queens 8))

SICP-2.41 solution

(define (triple-sum n s)
  (filter
    (lambda (tri)
      (if (= s
             (+ (car tri)
                (cadr tri)
                (caddr tri)))
        #t
        #f))
    (flatmap (lambda (i)
               (flatmap (lambda (j)
                          (map (lambda (k)
                                 (list i j k))
                               (enumerate-interval 1 n)))
                        (enumerate-interval 1 n)))
             (enumerate-interval 1 n))))

SICP-2.40 solution

(define (unique-pairs n)
  (flatmap
    (lambda (i)
      (map (lambda (j) (list i j))
           (enumerate-interval 1 (- i 1))))
    (enumerate-interval 1 n)))

functional风格的多重循环

受Scheme启发得来的Python版。。。

map(
    lambda i: map(
        lambda j: (i, j),
        range(100, 110)),
    range(0, 9))

说白了就是像map,filter这种东西本身就隐含了循环的成分。集大成者list comprehension更是如此。 

分页共1页 1