LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1967|回复: 13

我已经将fcitx移植到window下的freepy自由拼音输入法中,将其变成自由拼音开源五笔输

[复制链接]
发表于 2004-10-20 22:14:31 | 显示全部楼层 |阅读模式
不过,还在改善之中。
如果需要,将提供原码。



我已经在如下五笔爱好者网站提供了下载。欢迎大家试用!
http://wbfans.51web.cn/bbs/dispb ... ID=13300&page=1

安装程序源码:(已经加入98码表)

ftp://wbfans:wbfans@202.102.202. ... freepyfcitx31b7.rar

安装程序源码:(已经加入98码表)

ftp://wbfans:123456@61.152.99.14 ... freepyfcitx31b7.rar

会用FTP软件的朋友也可到K空间或火红空间中的“★★★★小企鹅五笔”目录中下载。
发表于 2004-10-20 22:42:07 | 显示全部楼层
呵呵……我喜欢……
在哪儿可以下载?
 楼主| 发表于 2004-10-21 09:12:35 | 显示全部楼层
Yuking你好。
经过编程,我才发现你对五笔编码的编排方式是最高效的。
以前,有个网友要求你将码表按ucdos或者极点中文的方式排列,我试验了一下,发现不但编程麻烦大了,而且输入的反映也慢了,完全失去了fcitx输入时的轻灵的感觉。所以我又采用了你的码表方式。
因为我是业余编程爱好者,所以水平有限,只是利用空闲时间,分析代码,看懂一部分后,刚思索可改进的地方,接着设定步骤改进,调试,所以进度不快。
我在分析了你的1.8.5的五笔部分的代码后,结合对freepy的分析,将fcitx五笔部分的几个函数移植过去。现在刚刚完成对词频调整,查询五笔编码的移植。但使用的感觉已经很好。
由于对自动造词的机制不是很清楚,现在正在摸索学习中。不知您能否告诉我。
关于代码,我将邮寄给您。还得先谢谢您开放了fcitx的原码。
在这个输入法中,我加入了一个特别的功能,就是汉字输入日文输入的轮换,这是我在学习使用日语时的一个想法,借助于fcitx与freepy,将它实现,心里也是很快乐的。
 楼主| 发表于 2004-10-21 19:26:22 | 显示全部楼层
报告:今天有空,完成了自动造词部分的移植。现在我的这个输入法已经很好用了,快让我爱不释手了。
刚才荣幸地收到yuking的来信,给我很大鼓励。我会继续努力。将vc学得更好,将本输入法继续发展。
 楼主| 发表于 2004-10-27 01:49:56 | 显示全部楼层
关于自动造词的机制,我是这样设想的。首先将输入的若干个汉字串进行保存,我保存了500个汉字,同时保存每个汉字的前两个编码,和第一个编码。这样就形成了三个字符串。
当自动造词时,就在这三个字符串中寻找,效率比在所有的码表中查找的效率高多了。
经过编程,我实现了对最后输入的50个汉字的任意连续的2-8个汉字串进行自动造词。这样的功能已经相当实用了。
希望与大家一起讨论。
发表于 2004-10-27 08:11:20 | 显示全部楼层
是,我一直想改进这个算法。
如果记录汉字及编码,用户以一级简码输入的字还是得查找整个码表。
因此我是想以将码表结构改进一下,将单字和词组分开,这样肯定会好很多
 楼主| 发表于 2004-10-27 13:47:36 | 显示全部楼层
是这样的,保存的是用findwbcode这个函数取得的编码的前两个,所以即使用户以一级简码录入也没有关系。因为我并不是通过记录输入编码的方式来取得编码的。而是对每个输入的汉字都调用findwbcode来取得的。新版的安装程序及原码已经给你发送了一份,请试用并且指正。
 楼主| 发表于 2004-10-27 13:52:49 | 显示全部楼层
//放宽对编码要求,只要有两个编码就行,本来要求>2。
//如果放宽到一个编码,可能带来一些问题,由于一级简码不是很规范。
//由于二级简码已经比较规范所以先开放到>=2

char           *FindWuBiCode (char *strHZ)
{
    WBRecord       *recTemp;

    recTemp = wubiDictHead->next;
    while (recTemp != wubiDictHead) {
        if (!strcmp (recTemp->strHZ, strHZ)) {
            if (strlen (recTemp->strCode) >=2)
                return recTemp->strCode;
        }
        recTemp = recTemp->next;
    }

    return NULL;
}
这是您的FindWuBiCode函数,我仅加了一个等号等号。
 楼主| 发表于 2004-10-27 14:24:43 | 显示全部楼层
最初由 Yuking 发表
是,我一直想改进这个算法。
如果记录汉字及编码,用户以一级简码输入的字还是得查找整个码表。
因此我是想以将码表结构改进一下,将单字和词组分开,这样肯定会好很多


对的,用户在录入任何一个汉字时,都需要查找整个码表,但次数只要一次(我把它放在提交汉字串时进行)。这一次完成之后,我们将查到结果保存以备后用。之后再用时,就不要再重新搜索那83000个项目的码表了,只要搜索输入记录的1k,1k,0.5k这样小的三个字符串,所以速度提高了很多。

我作了个对比试验,并且得出如下结论:
采用记录的方式,对每个录入汉字一次,在输入时只要搜索1k的字符串相应的次数,其速度相当快,可以忽略不记(1/83),。


采用原先的方式,即使我们只要求对最新输入的四个汉字里进行组合,都有3+2+1次组合,也就是说要搜索整个码表6次。
以上次数分别对应两字词,三字词,四字词。

如果是要求对最新输入的五个汉字进行组合,4+3+2+1,即要搜索10次。

如果是要求对最新输入的八个汉字进行组合,7+6+5+4+3+2+1,即要搜索28次。这时的输入法已经反应很迟钝了。

如果是要求对最新输入的50个汉字进行组合,最大的词组为8个汉字,有49+48+47+46+45+44+43+42,即364次。如果采用原方案,这时将发现计算机很忙,但是效率很低,因为它在作大量的无用功。
以上次数分别对应两字词,三字词,四字词,五字词,六字词,七字词,八字词。

因此结论是,必须保存输入记录,这样才能为以后功能的扩展打下基础。
 楼主| 发表于 2004-10-27 14:42:24 | 显示全部楼层
最初由 Yuking 发表
是,我一直想改进这个算法。
如果记录汉字及编码,用户以一级简码输入的字还是得查找整个码表。
因此我是想以将码表结构改进一下,将单字和词组分开,这样肯定会好很多


struct TWBRECORD {
    char           strCode[5];
    BOOL                BeUser;
    char           *strHZ;
    struct TWBRECORD *next;
    struct TWBRECORD *prev;
};
typedef struct TWBRECORD WBRecord;

在您的五笔结构里,我加入了一个参数:BOOL                BeUser;
我把词库分为系统词库与用户词库。系统词库保持相对稳定,只要在结束时保存一次就行了。而用户词库可以进行较多次数的保存,比如我设定输入20次,保存一次,每新造一个词组保存一次。如何区分系统词还是用户词,就是靠这个参数来分别。我设定BeUser==1时为用户添加词,BeUser==0时为系统词。

在装载入词库时,分别读入两个码表文件。对于系统词自动设置BeUser=0;
对于用户词的装入采用插入的方式,这种方式比较费时,因为对每个用户词条都得搜索怎么码表以决定插到哪里。所以我编了个perl程序,当用户词库的词条积累较多时可以将它并入系统词库中。perl代码如下

open(INFILE, "wbx.mb") || die "Can't open 文件: $!\n";
open(INFILE1, "wbxusr.txt") || die "Can't open 文件: $!\n";
open(OUTFILE, ">wbxadded.txt") || die "Can't open 文件: $!\n";
@karalist=<INFILE1>;
$karanum=@karalist;
$karalist[$karanum]="zzzz zzzz";
@wblist=<INFILE>;
$prevkaraitem="";
foreach $karaitem (@karalist) {
        ($a, $b) = split(" ", $karaitem);
        $Notexit=1;
        foreach $wbitem (@wblist){
                ($c, $d) = split(" ", $wbitem);
                next if($c le $prevkaracode);
                last if($c gt $a);

                if($a eq $c and $b eq $d){
                        $Notexit=0;
                }
                print OUTFILE ($c," ",$d,"\n");
        }
        if($Notexit && ($a ne "zzzz")){
        print OUTFILE ($a," ",$b,"\n");
        }
$prevkaracode=$a;
}
close(INFILE);
close(INFILE1);
close(OUTFILE);

这样就可以解决问题了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表