首页 技术 正文
技术 2022年11月18日
0 收藏 771 点赞 4,259 浏览 3032 个字

最近在使用一款app背单词的时候,会在某个单词下面,列出与之相类似的单词。于是我在想这个功能是如何做的,自己使用php版本,做了个简单的例子。

大致思路如下:

1、生成英文单词库,并将单词放置redis里(当然放数据库也可以)

首先我们看第一步,我的做法是,从网上找一个很大的文本,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();// 下一行
}
}
}

  

这个程序代码,可能要执行比较长的时间,根据个人电脑而定,反正我的电脑执行了差不多有个把小时。好吧,总之这样,我们自己就制作了个词库,虽然并没有包含所有单词,不过至少测试是可以的啦。

2、得到用户单词,生成与之相类似的单词

我们开始处理第二步,我们需要得到用户单词,生成”编辑距离”为1的所有单词。

那么什么是”编辑距离”为1的单词呢?大概有如下几种情况

(1)deletes:依次删除word的每一位后、所形成的所有新词。比如,’abc’对应的deletes就是 [‘bc’, ‘ac’, ‘ab’] 。

(2)transposes:依次交换word的邻近两位,所形成的所有新词。比如,’abc’对应的transposes就是 [‘bac’, ‘acb’] 。

(3)replaces:将word的每一位依次替换成其他25个字母,所形成的所有新词。比如,’abc’对应的replaces就是 [‘abc’, ‘bbc’, ‘cbc’, … , ‘abx’, ‘ aby’, ‘abz’ ] ,一共包含78个词(26 × 3)。

(4)inserts:在word的邻近两位之间依次插入一个字母,所形成的所有新词。比如,’abc’ 对应的inserts就是[‘aabc’, ‘babc’, ‘cabc’, …, ‘abcx’, ‘abcy’, ‘abcz’],一共包含104个词(26 × 4)。

有了思路后,代码如下:

public function getSimilarWord_1($word){
if(trim($word)){
$word = strtolower($word);for($i=0; $i<strlen($word);$i++){
$deletes[] = substr_replace($word,'',$i,1);
}
for($i=0; $i<strlen($word)-1;$i++){
$transposes[] = substr_replace($word,$word[$i+1],$i,1);
}
for($i=0; $i<strlen($word);$i++){
for($j=0;$j<strlen($this -> alphabet);$j++){
$replaces[] = substr_replace($word,$this -> alphabet[$j],$i,1);
}
}
for($j=0;$j<strlen($this -> alphabet);$j++){
$inserts[] = $this -> alphabet[$j] . $word;
}for($i=0; $i<strlen($word)-1;$i++){
for($j=0;$j<strlen($this -> alphabet);$j++){
$inserts[] = substr($word,0,$i+1) . $this -> alphabet[$j] . substr($word,-(strlen($word)-$i-1));
}}for($j=0;$j<strlen($this -> alphabet);$j++){
$inserts[] = $word . $this -> alphabet[$j];
}
$rs = array_unique(array_merge($deletes, $transposes, $replaces, $inserts));
echo count($rs);
$realWords = $this -> getRealWord($rs);
print_r($realWords);
return $realWords;}
}

好了,上面是一个简单的例子,实际生产环境中,还要考虑”编辑距离”为2的单词,而且上面这个程序是每次都要去库里面查找近似单词的,实际上,我们也可以再建张表,然后把所有单词的对应关系,跑出来,并存到对应关系表里面。这样用户输入一个单词之后,我们就可以直接查找出近似单词了。

当然这个程序再改改的话,也可以做成纠正用户输错单词的程序了。

完整代码:

http://git.oschina.net/kjr/kangjianrong_public/tree/master/similarWord?dir=1&filepath=similarWord&oid=3af896968d7c31003cfdfb06675ce0aa9f46e9c9&sha=f90f85b3c9dda717593e74f05053c5525b2cf710

欢迎转载,请注明出处:

http://www.cnblogs.com/kangjianrong/p/5818738.html

参考:

http://www.ruanyifeng.com/blog/2012/10/spelling_corrector.html

http://www.cnblogs.com/whoamme/p/3522467.html 

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,082
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,556
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,405
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,179
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,815
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898