查找字典中单词变位词 方法

来源:互联网 发布:tcp端口有哪些 编辑:程序博客网 时间:2024/06/11 02:53

   解决这个问题的许多方法都出奇地低效和复杂。任何一种考虑单词中所有字母的排列的方法都注定了要失败。

       eg:单词 “cholecystoduodenostomy” 有 22!(= 1.124*10^21) 种排列即使以闪电一样的速度第百亿分之一秒执行一种排列,也要消耗 1.1*10^9 秒。
       秒就是一个纳世纪,则 1.1*10^9 秒就是数十年

       啊哈!灵机一动。。。

       第一标识字典中的每一个词,使得在相同变位词类中的单词具有相同的标识
       第二将所有具有相同标识的单词集中在一起


        对于第一个问题,我们可以使用基于排序的标识:将单词的字母按照字母表顺序排列。
       eg:“deposit” 的标识就是 “deiopst”,这也是 “dopiest” 和其他任何在该类中的单词的标识。

       要解决第二个问题,我们将所有的单词按照其标识的顺序排序。我所知道的关于该算法的最好的描述就是 Tom Cargill 的翻手表示:先用一种方式排序(水平翻手),再用另一种方式排序(垂直翻手)

原理分析

排序排序最显而易见的用处就是产生有序的输出。该输出既可以是系统规范要求的一部分,也可以是另一个程序(也许是一个二分搜索程序)的前期准备工作。但是在变位词问题中,排序并不是关注的焦点。排序是为了将相等的元素(本例中为标识)集中到一起。这些标识产生了另外一个排序应用:将单词内字母排序使得同一个变位词类中的单词具有标准型。通过给每条记录添加一个额外的关键字,并按照这些关键字进行排序,排序函数可以用于重新排列磁盘文件中的数据。

二分搜索该算法在有序表中查找元素时极为高效。并且可用于内存排序或磁盘排序。唯一的缺陷就是整个表必须已知并且事先排好序。

标识:当使用等价关系来定义类时,定义一种标识使得类中的每一项都具有相同的标识,而该类以外的其他项则没有该标识,这是很有用的。对单词中的字母排序可以产生一个用于变位词类的标识。其他标识通过排序给出。然后使用一个计数来代表重复的次数(于是标识 “mississippi” 可以写成 “i4m1p2s4” 或将1省略 ---- “i4mp2s4”)。也可以使用一个包含26个整数的数组来标识每个字母出现的次数。标识的其他应用包括:美国联邦调查局用来索引指纹的方法,以及用来识别读音相同但是拼写不同的名字的 Soundex 启发方法:



变位词程序的操作流程演示

       我的变位词程序按三个阶段的 “管道”组织,其中一个程序的输出文件作为下一个程序的输入文件。第一个程序标识单词,第二个程序排序标识后的文件,而第三个程序将这些单词压缩为每个变位词类一行的形式。

eg:仅有6个单词的字典的处理过程




需要做的工作


1对单词文件做预处理(大写字母全部转换为小写字母)
2
. 对单词中的字母,以升序排序,生成单词对应的 “标识
3.
通过系统 sort 程序对标识以升序排序(将所有具有相同标识的单词归拢在一起)
4.
具有相同标识的单词归为一类
5. 任意输入一个单词,通过 第“2”步的方法生成单词对应的标识,用二分查找法,在第 “4” 步生成的单词类中找到该单词的变位词