【Programming Pearls】查找所有的变位词

来源:互联网 发布:mysql 视图查询效率 编辑:程序博客网 时间:2024/06/05 16:17

           给定一本英语单词词典(每个输入行一个单词,字母都用小写),怎么找出所有的变位词类。例如:“deposit”、“dopiest”、“posited”是同一类变位词。

         假如在词典中大约有230000个单词,即使一次简单的变位词比较至少也需要花一微秒的时间,总共需要230000个单词*230000次比较/个单词*1微秒/一次比较=52900*10^6微秒=52900秒=14.7小时。

 

快速算法:可以采用签名、排序、压缩三个步骤来处理上面的问题。
 

签名(sign):就是对单词内的字母按字典顺序进行排序,如deposit的签名是deiopst。

排序(sort):对所有的签名按字母顺序进行排序。

压缩(squash):将具有相同的前面进行压缩合并,放一个集合输出。

如下过程:

 

 签名sign和排序的代码如下:

 

int charcomp(char *x, char *y){ return(*x - *y); }#define WORDMAX 100int main(void){ char word[WORDMAX], sig[WORDMAX];while (scanf("%s", word) != EOF) {strcpy(sig, word);qsort(sig, strlen(sig),sizeof(char), charcomp);printf("%s %s\n", sig, word);}return 0;}

 

压缩合并squash的代码如下:

int main(void){ char word[MAX], sig[MAX], oldsig[MAX];int linenum = 0;strcpy(oldsig, "");while (scanf("%s %s", sig, word) != EOF)if (strcmp(oldsig, sig) != 0&& linenum > 0)printf("\n");strcpy(oldsig, sig);linenum++;printf("%s ", word);}printf("\n");return 0;} 

        注:该算法在 230000单词中,总共运行时间为 18 seconds: 其中 4 in sign, 11 in sort and 3 in squash.