標籤:
最近在使用一款app背單詞的時候,會在某個單詞下面,列出與之相類似的單詞。於是我在想這個功能是如何做的,自己使用php版本,做了個簡單的例子。
大致思路如下:
1、產生英文單詞庫,並將單詞放置redis裡(當然放資料庫也可以)
2、得到使用者單詞,產生與之相類似的單詞
首先我們看第一步,我的做法是,從網上找一個很大的文本,big.txt。這個文本包含了幾萬個單詞,然後利用正則,將裡面的單詞,拿出來並存到redis庫裡面。
但問題是,我們在使用php讀取大檔案時,並還要利用正則去匹配單詞的話,這個動作是非常消耗記憶體的,於是我的做法是,一行一行的去讀取文本,並把這行
裡面的單詞,在取出來,存到庫裡。
核心代碼如下:
public function word($perLine){preg_match_all(‘/[a-z]+/i‘,$perLine,$matches);if($matches[0]){foreach ($matches[0] as $key => $value) {$word = strtolower($value);if($this -> redisObj->exists($word)){$this -> redisObj->incr($word);}else{$this -> redisObj->set($word, 1);}}}}/** * 返迴文件從X行到Y行的內容(支援php5、php4) * @param string $filename 檔案名稱 * @param int $startLine 開始的行數 * @param int $endLine 結束的行數 * @return string */public function getFileLines($filename, $startLine = 1, $endLine=50, $method=‘rb‘) { $content = array(); $count = $endLine - $startLine; // 判斷php版本(因為要用到SplFileObject,PHP>=5.1.0) if(version_compare(PHP_VERSION, ‘5.1.0‘, ‘>=‘)){ $fp = new SplFileObject($filename, $method); $fp->seek($startLine-1);// 轉到第N行, seek方法參數從0開始計數 for($i = 0; $i <= $count; ++$i) { $lineContent=$fp->current();// current()擷取當前行內容 $this -> word($lineContent); $fp->next();// 下一行 } }}
這個程式碼,可能要執行比較長的時間,根據個人電腦而定,反正我的電腦執行了差不多有個把小時。好吧,總之這樣,我們自己就製作了個詞庫,雖然並沒有包含所有單詞,不過至少測試是可以的啦。
php匹配相似單詞