Time of Update: 2018-12-08
一、輸入緩衝 在介紹如何進行詞法分析之前,先來說說一個不怎麼被提及的問題——怎麼從源檔案中讀取字元流。為什麼這個問題這麼重要呢?是因為在詞法分析中,對字元流是有要求的,它必須能夠支援後援動作(就是將多個字元放回到流中,以後會再次被讀取)。先來解釋下為什麼需要支援後援動作,舉個簡單的例子來說,現在要對兩個模式進行匹配:圖 1 流的回退過程上面是一個簡單的匹配過程,僅為了展示回退過程,在後面實現 DFA 模擬器時會詳細解釋是如何匹配詞素的。現在來看看 C# 中與輸入相關的類,有
Time of Update: 2018-12-08
雖然文章的標題是詞法分析,但首先還是要從編譯原理說開來。編譯原理應該很多人都聽說過,雖然不一定會有多麼瞭解。簡單的說,編譯原理就是研究如何進行編譯——也就如何從代碼(*.cs 檔案)轉換為電腦可以執行的程式(*.exe 檔)。當然也有些語言如 JavaScript 是解釋執行的,它的代碼是直接被執行的,不需要產生可執行程式。編譯過程是很複雜的,它涉及到很多步驟,直接拿《編譯原理》(Compilers: Principles, Techniques and Tools,紅龍書)上的圖來看:圖 1
Time of Update: 2018-12-08
有了上一節中得到的Regex,那麼就可以用來構造 NFA 了。NFA 可以很容易的從Regex轉換而來,也有助於理解Regex表示的模式。一、NFA 的表示方法 在這裡,一個 NFA 至少具有兩個狀態:首狀態和尾狀態, 1 所示,Regex $t$ 對應的 NFA 是 N(t),它的首狀態是 $H$,尾狀態是 $T$。圖中僅僅畫出了首尾兩個狀態,其它的狀態和狀態間的轉移都沒有表示出來,這是因為在下面介紹的遞迴演算法中,僅需要知道 NFA 的首尾狀態,其它的資訊並不需要關心。圖 1 NFA
Time of Update: 2018-12-08
//Main複製代碼 代碼如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Fibonacci{ class Program { static void Main(string[] args) { Console.WriteLine("Would you like to know which
Time of Update: 2018-12-08
Regex是一種描述詞素的重要表示方法。雖然Regex並不能表達出所有可能的模式(例如“由等數量的 a 和 b 組成的字串”),但是它可以非常高效的描述處理詞法單元時要用到的模式類型。一、Regex的定義Regex可以由較小的Regex按照規則遞迴地構建。每個Regex r 表示一個語言 L(r) ,而語言可以認為是一個字串的集合。Regex有以下兩個基本要素:1.ϵ 是一個Regex, L(ϵ)=ϵ ,即該語言只包含空串(長度為 0 的字串)。2.如果 a 是一個字元,那麼 a
Time of Update: 2018-12-08
通常C#使用基於XML的設定檔,不過如果有需要的話,比如要兼顧較老的系統,可能還是要用到INI檔案。但C#本身並不具備讀寫INI檔案的API,只有通過調用Unmanaged 程式碼的方式,即系統自身的API才能達到所需的目的。對應讀寫的方法分別為GetPrivateProfileString和WritePrivateProfileString。GetPrivateProfileString中的各參數:lpAppName —— section的名稱lpKeyName ——
Time of Update: 2018-12-08
整數轉換為字串:char *itoa( int value, char *string,int radix);小數轉換為字串:sprintf(串, 格式控制符列, 資料);字串轉小數:double atof(const char *nptr);字串轉整數:int atoi(const char *nptr);測試代碼:複製代碼 代碼如下:#include<stdio.h> #include<stdlib.h> int main() { int a=2013420
Time of Update: 2018-12-08
該雜湊演算法為一個檔案產生一個小的二進位“指紋”,從統計學的角度來看,不同的檔案不可能產生相同的雜湊碼要產生一個雜湊碼,必須首先建立一個HashAlgorithm對象,通過HashAlgorithm.Create方法來完成。然後調用HashAlgorithm.ComputeHash方法,它會返回一個儲存雜湊碼的位元組數組,再使用BitConverter.Tostring()將其裝換為字串進行比較。源碼如下:複製代碼 代碼如下:public static bool
Time of Update: 2018-12-08
複製代碼 代碼如下:using System;using System.Collections.Generic;using System.Text;namespace WindowsFormsApplication1{ using System; using System.Drawing; using System.Runtime.InteropServices; using Microsoft.Win32; using System.Reflection;
Time of Update: 2018-12-08
複製代碼 代碼如下: private void button2_Click(object sender, EventArgs e) { // Create a request for the URL. WebRequest request = WebRequest.Create("http://www.baidu.com/"); // If required by the
Time of Update: 2018-12-08
通過調用Win32 API實現。複製代碼 代碼如下:public class User32API{ private static Hashtable processWnd = null; public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam); static User32API() { if (processWnd == null) { processWnd =
Time of Update: 2018-12-08
複製代碼 代碼如下:[ThreadStatic] static char[] mTempChars; protected static char[] GetTempData() { if (mTempChars == null) mTempChars = new char[1024 * 64]; return mTempChars; } public
Time of Update: 2018-12-08
一直對搜尋、過濾很好奇,覺得他們很有技術含量,只有非常NB的人才能做。很想知道他們的原理,實現這樣的功能,設計是不是必須得非常NB非常奇特,代碼是不是要寫得非常好,效能非常高。總之這一切都不是我這樣層級的人能做的。直到我看了《編程珠璣(第二版)》中的這麼一段文字:“假定我們可以在執行搜尋之前對常值內容進行預先處理,那麼我們可以建立一個撒列表(或者搜尋樹),為文檔中的每個不同的單詞建立索引,並為每個單詞的每次出現儲存一個鏈表,這樣的逆向索引使得程式可以很快的找到給定的單詞,為了尋找短語,我們可以對
Time of Update: 2018-12-08
泛型可以用於類,也可以用於函數。如泛型類:複製代碼 代碼如下:public class MyClass<T> { public T MyElement { get; set; } }泛型函數:複製代碼 代碼如下:public T ReturnElement<T>() { throw new NotImplementedException(); }但是當需要對MyElement進行執行個體化的時候,卻不能使用new(),只要添加如下代碼即可進行執行個體化了:
Time of Update: 2018-12-08
1. C#實現.NET組件與COM組件的互操作[DllImport("kernel32.dll")]這叫引入kernel32.dll這個動態串連庫。這個動態串連庫裡麵包含了很多WindowsAPI函數,如果你想使用這面的函數,就需要這麼引入。舉個例子:[DllImport("kernel32.dll")]private static extern void
Time of Update: 2018-12-08
我在《Linux 多線程服務端編程:使用 muduo C++ 網路程式庫》第 1.9 節“再論 shared_ptr 的安全執行緒”中寫道:(shared_ptr)的引用計數本身是安全且無鎖的,但對象的讀寫則不是,因為 shared_ptr 有兩個資料成員,讀寫操作不能原子化。根據文檔(http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety), shared_ptr
Time of Update: 2018-12-08
在自然語言處理(NLP)研究中,NGram是最基本但也是最有用的一種比對方式,這裡的N是需要比對的字串的長度,而今天我介紹的TrieTree,正是和NGram密切相關的一種資料結構,有人稱之為字典樹。TrieTree簡單的說是一種多叉樹,每個節點儲存一個字元,這麼做的好處是當我們要做NGram比對時,只需要直接從樹的根節點開始沿著某個樹叉遍曆下去,就能完成比對;如果沒找到,停止本次遍曆。這話講得有些抽象,我們來看一個實際的例子。假設我們現在詞庫裡面有以下一些詞:上海市 上海灘 上海人 上海公司
Time of Update: 2018-12-08
儘管這個概念已經讓人說濫了 ,還是想簡單記錄一下, 以備以後查詢。複製代碼 代碼如下:#ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)#else#define DEBUG_CLIENTBLOCK#endif#define _CRTDBG_MAP_ALLOC#include <crtdbg.h>#ifdef _DEBUG#define new
Time of Update: 2018-12-08
複製代碼 代碼如下:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Text.RegularExpressions; namespace
Time of Update: 2018-12-08
複製代碼 代碼如下://調用API [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)] public static extern IntPtr GetForegroundWindow(); //獲得本表單的控制代碼