编程珠玑之第二章questionC: 求变位词问题
2015-01-10 10:45
281 查看
问题描述:
C. 给定一个英语词典,找出其中的所有变位词集合。例如,“pots”、“stop”和“tops”互为变位词,因为每一个单词都可以通过改变其他单词中的字母的顺序来得到。
问题解析:
1、变位词具有相同的长度,相同的字符,唯一的区别就是这些相同的字符按照不同的顺序排列成不同的字符串而已。如果有一种方法唯一标识这些相同的字符,那么这个问题好解决了。
解决方案:
方案1:按照字母顺序对每个单词进行标识并把这些具有相同标识的词集合到一起。
(1)将输入文件中的所有单词加标识并输出到另一个文件中。代码如下:
简单的测试数据dictionary.txt和生成的数据sign_dictionary.txt见:
http://download.csdn.net/detail/johnnyhu90/8346745
(2)将有标识的输出文件中所有的词依(标识,单词)对的形式存储到内存。这里使用C++的mutimap和set来完成,代码如下:
输出结果如下:
心得与疑惑:
1、当我们把所有的单词进行标识并且将标识和其对应的单词存储到硬盘的一个文件中,那么怎么样对这个文件按照标识进行排序(假设内存不能够一次性全部加载这些数据)?
C. 给定一个英语词典,找出其中的所有变位词集合。例如,“pots”、“stop”和“tops”互为变位词,因为每一个单词都可以通过改变其他单词中的字母的顺序来得到。
问题解析:
1、变位词具有相同的长度,相同的字符,唯一的区别就是这些相同的字符按照不同的顺序排列成不同的字符串而已。如果有一种方法唯一标识这些相同的字符,那么这个问题好解决了。
解决方案:
方案1:按照字母顺序对每个单词进行标识并把这些具有相同标识的词集合到一起。
(1)将输入文件中的所有单词加标识并输出到另一个文件中。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include <cstdio> #include <cstdlib> // qsort #include <cctype> // toupper\tolower #include <cstring> // strlen #include <cassert> // assert #define WORDMAX 100 #define error( str ) fatal_error( str ) #define fatal_error( str ) fprintf( stderr, "%s\n", str ), exit( 1 ) int charcomp(const void* x, const void* y) { return *(char*)x - *(char*)y; } /************************************************************************/ // 函数名称:mytolower // 函数目的:将字符串中的大写字符转为小写字符 // 函数参数:lword:转换后的字符串,word:要转换的字符串 // 函数返回:转换后的字符串 // 使用条件: /************************************************************************/ char* mytolower(char* lword, char* word) { while ( *word != '\0' ){ if (isalpha(*word) && isupper(*word)){ *lword++ = tolower(*word++); } else { *lword++ = *word++; } } *lword = '\0'; // 末尾加结束字符 return lword; } /************************************************************************/ // 函数名称:add_sign // 函数目的:获取单词标识并输出到文件中 // 函数参数:rfile:要读文件,wfile:要写的文件 // 函数返回:无 // 使用条件:输入的单词长度小于100 /************************************************************************/ void add_sign(FILE* rfile, FILE* wfile) { assert(rfile != NULL && wfile != NULL); char word[WORDMAX], lword[WORDMAX], sign[WORDMAX]; while(fscanf(rfile, "%s", word) != EOF){ mytolower(lword, word); strcpy(sign, lword); qsort(sign, strlen(sign), sizeof(char), charcomp); fprintf(wfile, "%s\t%s\r\n", sign, word); } return; } int main() { FILE* rfile = fopen("dictionary.txt", "r"); if (NULL == rfile){ fatal_error("不能打开dictionary.txt文件!\n"); } FILE* wfile = fopen("sign_dictionary.txt", "w"); if (NULL == wfile){ fatal_error("不能打开sign_dictionary.txt文件!\n"); } add_sign(rfile, wfile); fclose(rfile); fclose(wfile); printf("生成完毕!!"); return 0; } |
http://download.csdn.net/detail/johnnyhu90/8346745
(2)将有标识的输出文件中所有的词依(标识,单词)对的形式存储到内存。这里使用C++的mutimap和set来完成,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include <iostream> #include <map> #include <set> #include <string> using namespace std; /************************************************************************/ // 函数名称:print_anagrams // 函数目的:输出打印所有的变位词 // 函数参数:rfile:要读文件 // 函数返回:无 // 使用条件:rfile是有(标识、变位词)对的文件 /************************************************************************/ void print_anagrams(FILE* rfile) { char word[WORDMAX], sign[WORDMAX]; multimap<string,string> angrams; std::set<string> myset; while(fscanf(rfile, "%s\t%s", sign, word) != EOF){ myset.insert(sign); angrams.insert(std::make_pair(sign, word)); } for (set<string>::iterator iter = myset.begin(); iter != myset.end(); ++iter) { multimap<string, string>::iterator it = angrams.equal_range(*iter).first; for (; it != angrams.equal_range(*iter).second; ++it){ std::cout << ' ' << (*it).second; } cout << endl; } return; } int main() { FILE* rfile = fopen("sign_dictionary.txt", "r"); if (NULL == rfile){ fatal_error("不能打开sign_dictionary.txt文件!\n"); } print_anagrams(rfile); fclose(rfile); printf("执行完毕!!"); return 0; } |
心得与疑惑:
1、当我们把所有的单词进行标识并且将标识和其对应的单词存储到硬盘的一个文件中,那么怎么样对这个文件按照标识进行排序(假设内存不能够一次性全部加载这些数据)?
相关文章推荐
- 《编程珠玑》第二章2.8 变位词 思路
- 编程珠玑-第二章问题A
- 位图法;海量数据处理之位图技巧;位图技巧;海量数据;编程珠玑第二章问题A;40亿整数;腾讯面试题
- 《编程珠玑 》第二章 问题A 总结
- 编程珠玑第二章问题A,B,C
- 编程珠玑第二章问题B: n元一维向量旋转问题之java实现
- 编程珠玑:第二章,3个问题
- 《编程珠玑》第二章三个问题A---查找40亿个32位整数中缺失的某个整数
- 《编程珠玑》第二章问题C:找出相同的英文单词(单词改变顺序可以互相转化即为相同)
- 向量abc转换为cba(如何交换非邻接内存块的问题) 编程珠玑 第二章 问题 5
- 编程珠玑之第二章questionB: n元一维向量旋转问题
- 编程珠玑第二章变位词1
- 编程珠玑:第二章 啊哈,算法三个问题
- 《编程珠玑》第二章-循环移位
- 《编程珠玑》 第二章 算法 习题
- {Programming Pearls}第二章--向量旋转问题
- 利用位运算解决排序问题(摘自编程珠玑)
- 变位词问题
- To be, or not to be; that is the question! 生存还是毁灭,这是个值得思考的问题。
- zju1763一个简单的化学问题A Simple Question of Chemistry