字典搜索算法,急需,请尽快!
有一英文字典文件,单词按字母排序以纯文本方式储存,请问有什么好的方法,搜索到指定词条。请注意字典非常庞大——600万单词、每个单词一行,不能使用 数据 库。请提出详细算法,并比较若干算法优劣。急需,请尽快。 问题点数:300、回复次数:26Top
1 楼clavy(土土酋长)回复于 2001-07-11 10:58:34 得分 75
运行最快使用hash表查找。
编程最快, 使用2分查找。
能够共享一下这个词库.嘻嘻.Top
2 楼clavy(土土酋长)回复于 2001-07-11 11:00:23 得分 0
能否共享一下这个词库? 如果是个拼写检查/破解用的字典就算了.Top
3 楼songhtao(三十年孤独)回复于 2001-07-11 11:19:33 得分 0
请说说hash的详细算法好吗?请注意600万单词不能一次读到内存。Top
4 楼sirarker()回复于 2001-07-11 12:53:26 得分 10
我觉得先建立一个近似平衡的二叉树作为 数据结构 ,这样根据二叉树的搜索算法效率可能会高一些Top
5 楼starfish(海星)回复于 2001-07-11 13:15:39 得分 40
用B树或者B+树存储在硬盘上,搜索的时候用外部检索的算法,比如多路归并 技术 之类。自己查查相关资料吧。Top
6 楼Arter(阿蒂尔)回复于 2001-07-11 13:18:27 得分 80
1.可以考虑建多级索引
第一级:A,B....Z;
第二级:aa,ab,ac,.....,ze,..;
第三级:...;
2. 每级索引内用
Top
7 楼Arter(阿蒂尔)回复于 2001-07-11 13:30:30 得分 0
散列队列(hash表)查找。
即: A---0 (A与0对应,当然A可对应它的索引表地址)
B---1 ,
...
Z---25,
3.如果、要节省空间可以用starfish(海星)说的“用B树或者B+树存储在硬盘上,搜索的时候用外部检索的算法,比如多路归并技术之类。“
4."600万单词不能一次读到内存。"可以用类是页式系统(分页管理)的方法解决。
Top
8 楼starfish(海星)回复于 2001-07-11 14:32:19 得分 0
建议参考TAOCP (The art of computer programming)的第三卷,专门讲排序和检索的。
在超星数字化图书馆有,中文译名《计算机程序设计技巧(第三卷 排序和查找)》Top
9 楼dqyking(工作真累呀)回复于 2001-07-11 14:34:23 得分 10
查书
Top
10 楼clavy(土土酋长)回复于 2001-07-11 14:53:58 得分 0
to songhtao(三十年孤独)
hash查找就是根据的hash值进行查找. 设计一个hash函数, 这个hash函数能够根据一个单词, 计算出一个hash值. 而这个hash值就是这个单词的存放地址。
用2分查找, 时间复杂度是 O(log2(n)), 而使用hash查找的, 几乎是常数时间。
当然, hash函数要设计的好, 一次的命中率才高。这个你可以看数据结构方面的书。
我不知道你在什么机器上编程, 如果是UNIX系统, 不需要把单词读到内存, 可以用mmap系统调用, 把文件映射到内存, 直接把文件当成虚拟内存。由操作系统进行页交换。其效率还是很高的。
B树或者B+树编程比较麻烦, 尤其要写到文件中时, B+的查找复杂度为 O(logX(n)) , 其中X是每个节点的子节点数。Top
11 楼starfish(海星)回复于 2001-07-11 21:20:56 得分 0
TO:clavy(有巢无车氏)
如果使用哈希表的话,检索时间确实是O(1),但是那是对于内存中的线性编址的数据而言(即数据必须是线性的连续存储的,这样知道地址就可以在O(1)的 时间内存取数据)。但是对于硬盘上的文件,如果让操作系统来管理的话,不可能是连续存储的,一般是分散在硬盘上不同的簇里面,即使你知道某个记录的相对位 置,比如知道要找的记录是第100个记录,也无法在O(1)的时间内找到第100个记录,因为文件中的记录在硬盘上不是连续存储的,而是类似链表一样存 储,所以要找第100个记录,必须从头找起!所以,你所说的将文件映射成虚存的方法虽然方便但是效率很低,哈希技术也起不了作用。现在一般大型的数据库都 是用B+树将数据组织在硬盘上,跳过操作系统自己来管理硬盘的存取而不是使用文件系统!只有Access等小型数据库(其实Access根本算不上数据 库)才是简单地利用文件系统来管理数据。对于他的这个
问题
,自己管理硬盘存取不现实也没有必要,但是通过用B+树组织数据可以使得读盘的次数降到最低!所以我认为B+树和多路归并技术比较好。
Top
12 楼starfish(海星)回复于 2001-07-11 21:25:45 得分 0
对了,顺便说一下,对于复杂的大型数据库(比如原来的旧版本的IBM的DB2),也有一些是自己固定了一部分硬盘扇区专门作为数据库的存储区,或者 将整个硬盘作为数据库的存储区,这时候就可以利用哈希技术了,将数据的内容和它在硬盘上的扇区地址建立映射关系,以便在O(1)的时间内从硬盘上读出数 据,但是这种方法现在很少用,因为插入和删除数据以及整理数据库都很不方便。Top
13 楼AutoAsm(风流总被雨打风吹去)回复于 2001-07-11 23:42:38 得分 20
咱们就在宏观上讨论一下:
HASH表显然是最快的,但要找HASH函数是个问题,可以多级HASH,建议你到图书馆看看有没有将HASH函数的理论著作,我以前看到过一篇讨论散列的博士论文。
另外,如果只查找而不做任何改动的话,用TREE也是一个好方法。很快Top
14 楼big_tian(继续补充)回复于 2001-07-12 05:28:50 得分 10
600万 就是 6M
每个单词10words 是60M,现在计算机流行 128M
你的程序有60M?Top
15 楼clavy(土土酋长)回复于 2001-07-12 09:58:40 得分 0
to starfish(海星)
如果有频繁的插入/删除, 用B+数比较好, 可是编程比较麻烦。
如果数据不是线性存储的, 那么建个索引好了。
即使使用B+树来组织数据, 访问硬盘的数据的时候, 也还是通过操作系统来寻址的。也就是每次访问的复杂度为 B+树的访问复杂度*硬盘数据访问复杂度. :) 而使用hash的访问复杂度为 hash访问复杂度*硬盘访问复杂度.
一般的数据库系统, 例如UNIX的UFS文件系统, 它的硬盘管理实际上就是B树.
你所说的'绕过操作系统管理文件的数据库', 它们使用的并不是普通的文件, 一般是使用裸设备, 也就是把一个硬盘/分区 当成一个文件。我试验过的, 使用裸设备的情况下, Oracle比使用文件系统的文件存储数据 在IO上快约一倍。 这与oracle 公司公布的数据相同。 这些数据库系统不可能绕过操作系统访问普通文件, 因为在UNIX上, 文件系统千变万化, 这些文件系统可以共同存在于同一实例中, 而且多数UNIX系统厂商都有多种文件系统, Oracle是不可能在其中集成这许多的文件系统的。
把文件映射为内存的方法现在在unix中被普遍使用. 如果你经常使用strace / truss之类的命令的话, 就会发现, 多数的UNIX操作系统命令几乎不用read/write调用, 而用 mmap/munmap . 其效率只所以比read/write高, 是因为它的buffer只有1次复制。
其实, 现在Oracle有一种索引技术称为 bitmap index, 它实际上就是在一个数组里建立起与每行对应的标记。Top
16 楼clavy(土土酋长)回复于 2001-07-12 10:00:48 得分 0
上文中
"一般的数据库系统, 例如UNIX的UFS文件系统, 它的硬盘管理实际上就是B树."
~~~~~~~
应为
"一般的文件系统, 例如UNIX的UFS文件系统, 它的硬盘管理实际上就是B树."
~~~~Top
17 楼gofor()回复于 2001-07-14 11:05:51 得分 0
to starfish:
不同意你的说法:“比如知道要找的记录是第100个记录,也无法在O(1)的时间内找到第100个记录,因为文件中的记录在硬盘上不是连续存储的,而是类似链表一样存储,所以要找第100个记录,必须从头找起!”
如果已知“要读的记录”在文件中的偏移,文件系统可以根据文件分配表FAT快速找到“要读的记录”的物理扇区号,并完成读操作,无须从头找起。要说从 头找起,只是在FAT分配表中从头找起,这无须多少时间,因为FAT相对硬盘容量来说很小,而且多数情况下FAT已缓存到内存。本问题的关键是减少对外存 的访问次数,在内存中对FAT进行的查找不管次数多少,不应计入算法复杂度。Top
18 楼songhtao(三十年孤独)回复于 2001-07-14 14:46:16 得分 0
我是这样回答的,经理没说什么,要我参加
项目
,请大家帮我分析一下看看有什么问题。
字典搜索软件概要设计
1.引言
1.1 项目名称:
项目名称:字典搜索。
1.2 项目背景和内容概要:
1. 负 责 人:宋红涛
2. 内容概要:英文字典文件,单词按字母排序以纯文本方式储存。字典非常庞大——600
万单词、每个单词一行,不能使用数据库。
1.3 项目目的:
从大英文字典文件中快速搜索到指定单词
2.概要设计
2.1基本设计概念和处理流程
1.数据分块法。
1. 内存中建立若干固定大小数组,数组元素为指向单词字符串的指针。
2. 从文件拷贝单词到数组。
3. 采用分块查找法——块内无需有序,因为单词按字母排序,所以块内单词有序。块
内按二分法查找。
4. 块间有序,待查字符串与最后块最后一条记录比较,在块中,再匹配各块查找。否则,内存中无待查单词,从文件读入后续数据到内存。
5. 重复2-4直到单词查到或查找失败。
优点:算法简单,有一定效率。
缺点:可能造成内存碎片。但可通过定期内存重组解决。有一定磁盘访问次数,可能降低效率,但可通过调整分块数和分块大小优化。
2. 分级索引法
1. 为英文字典建立索引文件
2. 索引文件格式:
单词(定长字符串) 单词偏移量(长整数)
3. 读索引到内存一个表中
4. 查找索引,找到单词在文件中存在范围。
5. 直接在文件中查找单词是否存在。
6. 可采用多级索引,把索引存到内存,提高效率,尽量减少访问磁盘次数。
优点:效率高,速度快。
缺点:需要进行索引维护,索引的建立方式对性能影响较大,需要着重考虑。
3. 局部缓存法
1. 建立一小文件缓存经常访问的单词
2. 利用高速缓存匹配算法查找单词。
优点:20%的单词访问概率为80%极大的提高访问速度
缺点:高速缓存算法有多种,需要适当选择,建议采用自组织线性表法(1.移至顶端、2.交换、3.频率计数(不推荐)),实践证明简单、有效。
补充:最好和其他算法综合使用,以便一旦高速缓存未命中,也能较快的查找或证明查找失败。
4.查找树法
1. 建立B/B+树。
2. 叶为单词在文件中的偏移量,分子节点存储关键字。
优点:适合大量数据的快速查找,尤其是数据库。
缺点:算法较复杂,关键字的选择特别重要。
5.散列表法
优点:精确匹配效率高
缺点:不改变字典文件结构,我不知道实现。拟单词定长,因为是根据单词找地址,因此查找效率高,但插入删除涉及到大量磁盘i/o效率会极低,只能在后台进行。最后散列函数的选择是一个重点。
3.说明
时间仓促,来不及仔细考虑,也未涉及到具体实现。只是一个不完善的思路。
Top
19 楼clavy(土土酋长)回复于 2001-07-14 17:07:57 得分 0
说说你的平台.
Top
20 楼songhtao(三十年孤独)回复于 2001-07-15 12:40:10 得分 0
windowsTop
21 楼ldy(罗大佑)回复于 2001-07-15 15:11:53 得分 10
:)Top
22 楼lins(Anders*小明)回复于 2001-07-16 10:31:56 得分 10
关注!!
大家多多讨论才是!我听着呢!!Top
23 楼YYboy()回复于 2001-07-18 14:08:11 得分 5
字典搜索算法,急需,请尽快!
RE: Money,急需,请尽快!Top
24 楼hz1101(lake)回复于 2001-07-18 16:21:10 得分 10
@_
@Top
25 楼YYboy()回复于 2001-07-19 18:36:51 得分 0
单词按字母排序以纯文本方式储存。字典非常庞大——600
万单词、每个单词一行,
RE: you are crazy!Top
26 楼minkerui(你好)回复于 2001-07-19 20:11:30 得分 20
想做解密软件吗?用SQL吧Top