Skip to main content

· 2 min read

314 Binary Tree Vertical Order Traversal

原題目是付費題目,有興趣看到完整的請自行付費觀賞,在此就不提供超連結了。

Introduction

  • 給定一個 binary tree,將此 tree 以 vertical 的方式走過,
  • 輸出時,從最左邊開始輸出
  • 相同 colume 的算同一個 group,若屬於同 row 且同 colume,則從左邊開始算起

Example

        0
/ \
1 4
/ \ / \
2 35 6
/ \
7 8

輸出為 [2][1] [0,3,5][4,7] [6][8]

Solution

這題不太困難,基本上可以採用 BFS 來搜尋整個 tree,然後加入一個 index 的欄位,root 的 index 是 0,往左遞減,往右遞增,在 BFS 的過程中,就把相同 index 都收集起來,最後再一口氣輸出即可。

pseudo code 如下

queue.push(pair(0, root));
while (!queue.empty()) {
index = queue.front().first;
node = queue.front().second;

ans[index].push(node->val)

if (node->left)
queue.push(pair(index-1, node->left);
if (node->right)
queue.push(pair(index+1, node->right);
}

return ans;

· 6 min read

還記得以前在工三讀書時,常常看到 Chun Norris 坐在我前面,然後畫面上是一張一張的卡片在不停地翻動,每張卡片上面都標記者一個日文單字, 看他快速地翻閱這些卡片,感覺就是在背頌單字,那時候也就沒有去想太多了。

沒想到過了幾年後,Chun Norris 竟然出書了!!! 英、日語同步Anki自學法:我是靠此神器,最短時間通過日檢N1、多益975分

看到這個消息後,就馬上預購了一本這個書,不但捧朋友的場,同時也順便瞭解看看到底 Anki 是什麼樣的東西。

對於想瞭解 Anki 基本操作的,可以參考這邊 經過了一陣摸索後,也開始使用了 Anki 來幫助我背單字,不過由於內建的一些卡片集(Deck)大都偏向特定主題,如托福、多益等 ,所以我後來也自己創建了一個卡片集給我自己使用。 在卡片編輯的部分,原本都是透過Anki application上面的 GUI 去操作編輯,填寫正反兩面的卡片資訊。 所以本來的流程是這樣

  1. 我看小說/文章
  2. 使用手機的 APP 去查詢單字
  3. 定期開啟 Anki 將 APP 內的歷史單字一個一個透過線上字典服務去查詢
  4. 將查詢的結果複製貼上到 Anki內,並轉成Anki的卡片

上面第三步驟最花費時間,當卡片數量一多的時候,其實要非常可怕的 那時候APP內大概有五六百個查詢過的單字,每個單字花20秒去填寫,也要整整三個小時不間斷才有辦法處理完畢。

有鑑於未來單字量只會愈來愈多,這樣手動下去實在不是辦法,因此腦筋就轉了彎一下,看有沒有辦法讓上面的步驟簡單化 上述(1),(2)這兩個步驟是不可避免的,那(3),(4)這兩個步驟就是主要處理的對象了。

針對我的目標,我將其拆成兩部分

  1. 給定一個單字,想辦法自動獲得其發音解釋
  2. 從上述的輸出中,將其自動變成 Anki 的卡片,然後塞到我的卡片集(Deck)中

針對第一點,我使用 python 作為我的程式語言,然後很偷懶的就拿了 yahoo 字典當作我的搜索來源 於是用了 python + BeautifulSoup + urllib 來爬網頁, 於是就網頁爬阿爬~就爬出了發音解釋了,這邊一切搞定

再來第二點,想要自動加入倒 Anki 的資料庫中,於是就到github去翻一翻,還真的翻到有人寫好已經可以用的工具 addToAnki,這個作者使用 python 撰寫,提供一個 tool 讓第三方可以將卡片的內容輸入進去後,自動轉為卡片並且塞到對應的卡片集中。 雖然我個人是更偏向去呼叫 library 而不是只接呼叫 tool 來處理,不過我的目的能達成就好,所以就將我前面的程式碼跟他的結合起來。目前將此結果放在這邊 同時我也發送了一個 pull request 到原先作者那邊,把我的使用情境當作一個多的範例使用,不過我看作者也兩三年沒碰了,應該也不會去接收我的 PR XDD

最後我的流程就是

  1. 遇到不會的單字
  2. 使用手機查詢單字
  3. 定期將查詢過的單字匯出成一個文字檔
  4. 將該文字檔送給我的 python 去處理,等他自動處理好即可。

上次一口氣加了四百多個單字,總共花費十五分鐘左右,大部分的時間應該都是消耗再去爬 yahoo dict這邊,目前這樣已經滿足我的需求。

· 2 min read

Basic

  • commit所使用的編輯器會依照下列優先度去選擇,

    1. GIT_EDITOR 環境變數
    2. core.editor 的設定
    3. VISUAL 環境變數
    4. EDITOR 環境變數
    5. vi 指令
  • 變動檔案請用 git mv,使用git rm要注意檔案系統內的檔案會被真的刪除。

  • git log可以列出簡略的coommit資訊

  • git show [commit id] 可以看詳細的commit資訊,可以加上commit ID來指定特定的commit

  • git show-branch --more=10 可以看當前bracnh的詳細commit資訊,由--more控制數量

Configuraion

總共有三種設定方式,優先度如順序

  • .git/config, 可以用 --file或是預設的方式操作
  • ~/.gitconfig, 可以用 --global操作
  • /etc/gitconfig,可以用 --system操作
git config --global user.name "hwchiu" (2)
git config user.email "[email protected]" (1)
  • 可以透過 git config -l列出當前所有的設定
  • 可以透過 --unset來移除設定
git config --unset --global user.name

· 3 min read

本篇文章是用來記錄以前修課關於 Shell Script 的作業

Introduction

用Unix的指令,透過pipe的方式完成下列要求

  • 計算當前目錄底下資料夾的總數
  • 計算當前目錄底下檔案總數
    • 只有計算regular file.不考慮FIFO、LINK
  • 計算所有檔案大小和 (Byte)
  • 顯示前五大的檔案名稱
  • 只能使用PIPE,不能使用 $$ ; || & > >> <

Implement

  • 使用ls來取得所有資料夾跟檔案的資訊
    • -l 可以顯示詳細資訊,這邊我們要取得的是 檔案大小
    • -R 遞迴的往每個資料夾繼續往下找
    • -A 不要把...給顯示出來,因為這種當前目錄的東西我們不需要
  • 使用sort來幫忙排序,找出檔案大小前五個
    • -r 排序結果反過來,由大到小排序
    • -n 排序的時候,採用數字的方式去排序,不使用字母大小去排序
    • -k 指定第幾個欄位要排序
  • 使用awk作最後的處理,找出前五大,印出所有檔案大小和
    • 因為再ls -l的結果中,會有很多資訊,包含 ./cs/.svn/pristine/74: 或者 total 28,所以awk再處理的時候,先用NF判斷該行的欄位數,至少要有9個欄位才處理 if(NF>=9)
    • 接下來針對檔案是資料夾還是檔案,做全部的計數,可以由 -rw-r--r-- 的第一個欄位來決定,如果是d就代表資料夾,否則就是檔案。 這邊我使用 regular expression來判斷 ($1 ~/^d/)? (dir=dir+1) : (file=file+1)(size=size+$5),此外如果是檔案得話,就順便把大小也計算一下
    • 執行過程中,因為剛剛已經排序過了,所以 前六行都把大小印出來, if(NR<6) print NR": "$5" "$9}
    • 最後就把所有資訊都列印出來

ls -RlA | sort -rnk 5 | awk '{ if(NF>=9) ($1 ~/^d/)? (dir=dir+1) : (file=file+1)(size=size+$5); if(NR<6) print NR": "$5" "$9} END{ print "Dir = "dir"\n" " File = " file"\n" "total = "size}'

· 4 min read

之前機器因為ZFS空間滿了,因為平常有再作snapshot的緣故,導致東西都刪除不了 因為刪除的時候都會有一些metadata的寫入,導致整個zfs動彈不得,這時候就花了很多時間再研就怎麼處理 這邊稍微記錄一下ZFS相關得操作。 ZPOOL的來源可以是device也可以是files,這邊就用兩個檔案當作來源。

Files

  • sudo dd if=/dev/zero of=/zfs1 bs=1M count=256
  • sudo dd if=/dev/zero of=/zfs2 bs=1M count=256

Zpool

  • create a mirror pool
    • zpool create ftphome mirror /zfs1 /zfs2
  • destroy a pool
    • zpool destroy ftphome
  • check zpool status
    • zpool status <pool>
  • export pool ( 把某些pool export出去,暫時不使用)
    • zpool export ftphome
  • import pool ( 把被export 的pool 重新import回來)
    • zpool import -d / ftphome (用-d指定你檔案的位置,預設會去吃/dev/)
    • 以我的範例來說,當import回來後,名稱會變成 //zfs1, //zfs2,多了一個/,原因不明中。
  • attach ( 只能對mirror使用)
    • zpool attach ftphome /xxx
  • detach ( 只能對mirror使用)
    • zpool detach ftphome /zfs1

還有offline,online,remove...,剩下的就要用的時候去man zpool,還滿詳細說明的。

ZFS database

  • set attributes zfs set key=value <filesystem|volume|snapshot>
    • zfs get compression ftphome
    • zfs set mountpoint=/home/ftp ftphome
  • get attributes zfs get key <filesystem|volume|snapshot>
    • zfs get compression ftphome
  • snapshot
    • zfs snapshot ftphome@today
    • zfs list -t snapshot

其他

  • 假如你的ZFS有使用snapshot同時空間又滿的話,這時候會發現所有檔案都會刪除失敗,都會得到空間不足的訊息,這邊稍微模擬一下該情況,並且想辦法解決此問題。

模擬情況

snatshot 該zfs

  • zfs snapshot ftphome@today
  • zfs list -t snapshot 看一下是否有成功

塞爆該空間

  • zfs list 看一下還剩下多少空間
  • dd if=/dev/random of=/home/ftp/file bs=1M count=256
  • cd /home/ftp
  • rm file => 應該會得到 No space left on device空間不足的訊息。

解決問題

ZFS 變大容易(多塞個硬碟即可),變小困難(幾乎無法),因此當ZFS的硬碟滿的時候,有兩種做法

  1. 再加入兩個新的硬碟,然後合併到目前的zpool,可是這樣就會變成有兩份mirror。
  2. 準備兩個更大的硬碟,把原本的zpool內的data全都複製過去。 這邊使用第二種做法

先幫本來的pool加入一個檔案,增加本來的空間,如此一來才可以做更多操作

  • dd if=/dev/zero of=/zfs5 bs=1M count=128
  • dd if=/dev/zero of=/zfs6 bs=1M count=128
  • zpool add ftphome mirror /zfs5 /zfs6
  • zfs list (此時可以看到本來的空間變大了)

創造一個更大的zpool來取代

  • dd if=/dev/zero of=/zfs3 bs=1M count=512
  • dd if=/dev/zero of=/zfs4 bs=1M count=512
  • zpool create ftphome3 mirror /zfs3 /zfs4
  • zfs set compression=gzip-9 ftphome2

把資料複製過去

  • zfs snapshot ftphome@send
  • zfs send ftphome@send | zfs receive -F ftphome2
  • zfs list 看一下大小是否相同

mount新的,舊的砍掉

  • zfs umount ftphome
  • zfs set mountpoint=/home/ftp/ ftphome2
  • zpool destroy ftphome

做到這邊,就算完成了,成功的把本來的資料複製過去。 如果想要改變zpool的名稱,可以用exportimport來改名稱。

· 3 min read

最近重新整理vim的設定檔,意外的發現 http://yoursachet.com/ 這個網站滿好用的,可以根據你的需求來自動打造vim設定檔,對於不想動腦去研究設定檔而言的人來說是滿好用的工具 用滑鼠輕鬆點點就可以產生堪用的VIM了!!

vimrc 設定

set encoding=utf-8
set fileencodings=ucs-bom,utf-8,big5,latin1
set fileencoding=utf-8
set termencoding=utf-8
set number " 行號
set statusline=%<\ %n:%f\ %m%r%y%=%-35.(line:\ %l\ of\ %L,\ col:\ %c%V\ (%P)%)
set ai " 自動縮排
syntax on " 色彩標示

set tabstop=4 " tab使用四個空白取代
set shiftwidth=4 " 縮排空白數,要搭配set cin使用
set cin
set cursorline " 該行的線
set t_Co=256 " 支援 256 色
set textwidth=0
set backspace=2 "按下backspace會後退,道行首後會刪除到前一行
set showmatch "顯示括號配對情況
set nocompatible "用vim的特性去運行,捨棄vi的特性

" Pathogen
call pathogen#infect()
call pathogen#helptags()

filetype plugin indent on

" Nerdtree
autocmd VimEnter * NERDTree
autocmd VimEnter * wincmd p
let NERDTreeShowBookmarks=1
let NERDTreeChDirMode=0
let NERDTreeQuitOnOpen=0
let NERDTreeMouseMode=2
let NERDTreeShowHidden=1
let NERDTreeIgnore=['\.pyc','\~$','\.swo$','\.swp$','\.git','\.hg','\.svn','\.bzr']
let NERDTreeKeepTreeInNewTab=1
let g:nerdtree_tabs_open_on_gui_startup=0


set background=dark "背景顏色
colorscheme wombat
nnoremap <silent> <F5> :NERDTree<CR>
"normal mode的時候+數字 可以切換tab
nnoremap <Esc>1 gt1
nnoremap <Esc>2 gt2
nnoremap <Esc>3 gt3
nnoremap <Esc>4 gt4
nnoremap <Esc>5 gt5
nnoremap <Esc>6 gt6
nnoremap <Esc>7 gt7
nnoremap <Esc>8 gt8

NERDTree

更改呼叫方式,使用F5

nnoremap <silent> <F5> :NERDTree<CR>

在各界面中移動

  • 按照順序往下移動 (crtl+w+w)
  • 上一個view (ctrl+w+h)
  • 下一個view (ctrl+w+l)

切割視窗

  • 水平切割 (在該檔案前按i)
  • 垂直切割 (在該檔案前按s) i :水平 s :垂直

tab使用

  • 開新tab並且切換過去 (t)
  • 開新tab但不切換過去 (T)
  • 下一個tab (gt)
  • 上一個tab (gT)

· 2 min read

Introducion

Cscope 是一個用來trace code還滿方便的工具 我通常都用他來trace linuxe kernel code,雖然說有網頁版的reference可以使用,但是用起來不順手,網頁會卡卡的 因此還是習慣使用這種互動式的trace tools

Install

sudo apt-get install cscope on Ubuntu

portmaster devel/cscope on FreeBSd

Usage

詳細的可以參考man page. 通常我只有使用 -R 來觀看而已

第一次執行的時候,會花比較久的時間去建立一個cscope.out的檔案,會把一些相關資訊放進去

下次執行的時候就會利用該out檔案來作查詢。

其他

預設的情況下,cscope只能讀取

  • .c
  • .h
  • .l
  • .y

想要讓他讀取java或是cpp的專案,就必須要先自己建置該資料庫

  • find ./ -name *.cpp > cscope.files
  • fine ./ -name *.java >> cscope.files
  • cscope -bkq

前面兩行會把所有的檔案路徑都寫入倒cscope.files裡面

  • b:建立索引文件
  • k:建立索引文件時不會去搜尋/usr/local/目錄
  • q:生成cscope.out,加速索引,該檔案包含
    • locate functions
    • function calls
    • macros
    • variables
    • preprocessor symbols

接下來只要使用cscope就可以了

· One min read

文章轉移

  • rsync cycbuff
  • rsync db/history
  • 重新建立overview
    • ctlinnd pause 'make overview'
    • makehistory -x -O -b x: won't write out history file entries. O: Create the overview database b: Delete any messages found in the spool that do not have valid Message-ID: headers in them.
    • makedbz -i i:To ignore the old database
    • ctlinnd go 'over'

設定檔檢查

  1. inncheck (inn.conf)
  2. scanspool -v (active, spool)

更新相關設定

  • 重新編譯innd,進入innd src底下
  • ./configure --opetions
  • make && make update

創新的newsgroup

  • ctlinnd newgroup name
  • modity db/newsgroup

其他

  1. 創新newsgorup
  1. 執行innd & nnrpd 會噴權限不足
    • 檢查/news/bin/innbind 有無SUID

· 2 min read

Install

直接透過atp-get 安裝即可

sudo apt-get install sphinx

Config

安裝完畢後,執行

sphinx-quickstart就可以基本設定了

每個選項都有說明,基本上都採用預設值即可

  • 設定檔: conf.py

    • 外掛管理
    • 資料夾結構管理
    • 一些通用參數,如作者名稱,版本...等
  • 主要的檔案: index.rst -. 檔案的結構 -. toctree

index.rsta

Lab Meetgins
=============
.. toctree::
:maxdepth: 4
:titlesonly:

20130924.rst
20131001.rst

國科會 meetings
===============
.. toctree::
:maxdepth: 4
:titlesonly:

20130925.rst

這邊我定義兩個toctree,每個toctree底下又會有其他的rst,結構大概是這樣

  • Lab Meetings
    • 20130924.rst
    • 20131001.rst
  • 國科會 meetings
    • 20130925.rst

總共兩個分類,每個分類底下的文章都是一個額外的rst檔案

在toctree底下的都是一些設定參數

  • maxdepth : 最大深度
  • titlesonly : 在首頁面只顯示子類的標題

Write

Sphinx採用的reStructuredText 格式跟markdown很類似,但是複雜了一些 官方網站有滿詳細的介紹,有需要時再去參考即可

Build

如果想要轉成html網頁,有兩種方法可以執行

  1. sphinx-build -b html . NSLMeeting 意思是建置html的網頁, 然後以當前目錄為source 來源,然後把檔案build到NSLMetting去。

  2. make html 在Makefile中定義了相關得動作,當執行make html的時候,其實就是執行 sphinx-build -b html . _build/html

這邊因為我想要直接弄到別的資料夾,所以我直接設定aliase去執行方法1

目前對於這套軟體還在學習階段,有任何學習會繼續紀錄。

· One min read

記錄一下執行floodlight時,有ㄧ些參數可以使用,都是用來指定設定檔的位置。

Floodlight configuraion:

--configFile ${configuration path}

Log configuraion:

-Dlogback.configurationFile=${FL_LOGBACK}

範例

java -Dlogback.configurationFile=logback.xml floodlight.jar --configFile floodlightdefault.properties