《编程珠玑》学习总结2-变位词

    第二章主要围绕三个问题

1、给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数

2、给定一个n元一维向量,循环左移i个位置,如n=8,i=3时,abcdefgh变为defghabc

3、如pots、stop和stops互为变位词,每个单词都可以通过其他单词改变字母顺序得到,找出字典中所有变位词

     对于1、主要考虑2分搜索

      对于3,百度笔试题刚考过,伤感,当时给略过去了,现在还是得看啊

      如果考虑暴力解法,含有n个字母的单词有n!种排列,还是很大的数量级的,书上是利用标志单词,标志则为对单词的字母进行排序后的结果,对字典遍历并对每个单词进行标记,还是很简单的事情,然后集中相同标志的单词,具有相同标志的单词,就是互为变位词了。

      配套代码的实现如下:

sign.c ,对每个单词进行标记,通过调用stdlib.h的qsort对单词进行快速排序

/* Copyright (C) 1999 Lucent Technologies */
/* From 'Programming Pearls' by Jon Bentley */

/* sign.c -- sign each line of a file for finding anagrams
    The input line "stop" gives the output line "opst stop"
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORDMAX 100

int charcomp(char *x, char *y)
{   return *x - *y;
}

int main()
{   char word[WORDMAX], sig[WORDMAX];
    while (scanf("%s%s", sig, word) != EOF) {
        strcpy(sig, word);
        qsort(sig, strlen(sig), sizeof(char), charcomp);
        printf("%s %s\n", sig, word);
    }
    return 0;
}
排序使用shell的内置命令sort,可参考 http://hi.baidu.com/renzhe19880626/blog/item/50fe964092c54d1c9213c66b.html

输出squah.c,不同标记就输出一个换行,相同标记则输出单词,使具有相同标记的单词都在同一行

/* Copyright (C) 1999 Lucent Technologies */
/* From 'Programming Pearls' by Jon Bentley */

/* squash.c -- print anagram classes on a single line
    The input lines "opst pots" and "opst stop" go to "pots stop"
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORDMAX 100

int main()
{   char word[WORDMAX], sig[WORDMAX], oldsig[WORDMAX];
    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;
}
楼主下载了个字典文件包含21w个单词,如下:

《编程珠玑》学习总结2-变位词_第1张图片

不得不说,linux的管道是个好东东,最终运行命令如下:

xia@Ubuntu:~/perl$ ./sign < DICT.TXT | sort | ./squah > list
生成list文件按照标志排序好了,有多个单词一行的则为变位词了,如:



     就这样吧




你可能感兴趣的:(《编程珠玑》学习总结2-变位词)