Posts tagged with C#

I don't know what is this pattern.

最近幾天每天都在寫 C#,寫的是某個自己要用的程式,由於只是自己用的,就只求速成,沒有花太多精神在設計上,直到這兩天才感覺到這樣不行,我實在重複了太多次相同的程式,因此決定改寫。

要描述我的需求太麻煩,直接看 code!我理想中的介面是長這樣:

Console.WriteLine(English.Hello());
Console.WriteLine(Chinese.Hello());
Console.WriteLine(Japanese.Hello());
Console.WriteLine(French.Hello());
  1. 上面的 EnglishChineseJapaneseFrench 都是 subclass,Hello() 是 static method,所以不需要實例就能直接呼叫,呼叫了之後就會回傳各國語言的 Hello。
  2. 同時我希望上述這些 subclass 只要繼承某個 class,就能有一個預設的 Hello(),當有必要時我再 override 這個 method。
Read More

Using SQLite Aggregate Functions in C#

昨天遇到一個 System.Data.SQLite 的 bug,老實說我不是很肯定它是不是 bug,因為這個 bug 在 2005 年就有人提出,卻到現在都沒有解決,可能其實是個 feature 也不一定 :p

一般我們使用 SQLite 查詢資料後,會先用 HasRows 確定資料存在,然後用 Read() 開始讀,用 GetValue()GetString()GetDouble() 等方法取資料。但是當 SQL 查詢句中包含了 Aggregate Functions1 時,HasRows 便必為 true。如果實際上查詢結果是空的,GetValue() 取得的值就會是 DBNull.ValueGetString() 會取得空字串,而使用 GetDouble() 來取值則會發生錯誤,因為 null 無法隱含轉換為 double 型態。

這有許多 Workaround,例如用 GetValue() 取出後,先判斷是否為 DBNull.Value,不是的話再轉換為 double。最簡便的方法則是先使用 IsDBNull() 檢查欄位是否為 DBNull,不是的話才執行 GetDouble()


  1. 例如 avg、count、max、min、sum 等。 

驗證 Base64 編碼字串

以往我以為驗證 Base64 編碼字串只要檢查它是由英文、數字、加號(+)、斜線(/)、等號(=)組成就好,但最近寫某個程式時踢到鐵板。我從原始資料中抓出一段 Base64 字串,無法使用 .NET 中的 Convert.FromBase64String() 對其進行轉換,但將同樣的字串交給 PHP 的 base64_decode() 卻又能正確處理。

經過我研究之後發現,Base64 編碼字串長度必為 4 的倍數,而等號的功能就是加在字串末端,確保其長度為 4 的倍數,因此等號也只會出現在字串末端,並不會出現在中間。此外,由於等號的功能只是要讓字串長度為 4 的倍數,故正確來說等號最多只能有 3 個,PHP 的 base64_decode() 則比較隨和,你高興的話,只要沒有 Out of Memory,要加幾個等號都沒關係 XD

最後整理一下驗證 Base64 編碼字串的方法:

  1. 字串由英文、數字、加號(+)、斜線(/)組成,末端可能還有 1—3 個等號(=)。
  2. 字串長度必為 4 的倍數,可以自行在字串末端增減等號的數目以符合此條件。

Klustering

目前是暑假,而我剛從大學畢業,還沒到研究所辦理入學,研究工作卻已經開始了。最近的 meeting 主要是聽學長報告,我們雖然有一位唯一僅有的學姐,我卻未曾有幸聽過她的報告。

因為暫時還算悠閒,在家沒事很無聊,於是 7/25 決定開始學習 C# 。我也考慮過 Java ,但是我對於 Java Virtual Machine 的印象很差,而且 C# 的 IDE 看起來很方便,就這樣有點隨便的決定了我要學的語言。

第一個程式先從基本的 K-means 演算法寫起(因為我指導教授的研究大致上都關於 K-means ,我想先寫一個來以後一定會用到 XD)。現在還沒有學生身份,不能到學校圖書館借書,只能靠著網路資料學,起初不熟悉時什麼都得查,進度好慢。到了 7/27 才完成基本的讀取 CSV 資料、分群。程式寫完便又開始無聊,就繼續作外觀方面的功能,例如讓點可以放大縮小、改使用者介面之類的。 C# 內建許多控制元件,而且不需要特別設定就會自動套用 XP 風格外觀,調整介面方面做得滿愉快的。

資料編輯器
分群結果


讓我印象比較深刻的,是主要資料的儲存型態我改了兩次,兩次都牽一髮而動全身,要改寫好多地方。 C# 的多維陣列有兩種作法:矩形陣列(Rectangular array)和不規則陣列(Jagged array),其中不規則陣列就像其他語言中的多維陣列作法,也就是陣列中的陣列(Array of arrays),因此每列長度可以不同;矩形陣列則像是表格,每列長度都相同。我的資料是一串座標,座標數量、維度不固定(但是同一份資料中座標維度必相同),起初我想這應該算是「動態陣列」吧!就用了 ArrayList(並不是前面提到的任何一種 XD),後來才發現我不需要動態,又改回矩形陣列,矩形陣列每列長度相同,跟我的資料剛好符合。最後一次則是改成不規則陣列,因為矩形陣列要取出其中一列很麻煩…… 這樣改了一圈感覺滿空虛的,都沒有用到 C# 的特殊功能 orz

7/30 沒事作,便試圖提昇 K-means 效能,第一個想法是最佳化找最近點的演算法,因為 K-means 中不斷的在找最近點。稍微翻了一點資料後,我覺得 kd-tree 看起來好像不錯,而這就是一段悲劇的開始…… kd-tree 其實是一種資料結構,為了將我的資料轉換為這種格式,我花了兩天才完成,主要的困難點在於他必須依照資料的各個軸排序,這不是用 Array.Sort() 就能辦到的事情,而我又不想使用 Wikipedia 上講的 Selection sort(時間複雜度很高耶!),最後把資料型態改成不規則陣列才作出來(這也是最後一次改資料型態的主因),這個部份完成後其他部份便很快也跟著完成了。

不過花了兩天研究 kd-tree 其實也還不算什麼,難過的是我寫完後才發現我不知道這要怎麼應用到 K-means 上…… XD

  • ← Older Posts
  • Newer Posts →