一 问题描述:
一个单词单词字母交换,可得另一个单词,如army->mary,成为兄弟单词。提供一个单词,在字典中找到它的兄弟。描述数据结构和查询过程。
二 解题思路:
本题有两个关键点:第一,如何设计英语字典的数据结构?第二,如何查找兄弟单词?
1. 设计英语字典的数据结构
如图,可以采用哈希链表的形式组织字典,而每个结点有三个域组成,分别是单词,频度和后继指针,频度表示这个单词被访问的次数,当我们访问某个单词时,它的频度会加1,然后应用程序根据频度重新调整该单词在链表中的位置,使得频度高的里链表头近,这样可以提高查找的效率。
2. 设计查找兄弟单词的算法
比如army 和amry是兄弟单词,我们只要对两个单词按同一次序,比如升序进行排序,排序后两个单词相等,那么这两个单词是兄弟单词。
3. 代码
/* This is a free Program, You can modify or redistribute it under the terms of GNU *Description:百度面试题--给定一个单词,从字典查找该单词的所有兄弟单词 *Language: C++ *Development Environment: VC6.0 *Author: Wangzhicheng *E-mail: 2363702560@qq.com *Date: 2012/12/30 */ #include <iostream> #include <cstdlib> #include <vector> #include <list> #include <string> #include <algorithm> #include <cctype> using namespace std; /* *单词结构体 */ typedef struct Word { string word; int freq; // 单词被访问的频度 struct Word *next; }Word; const int N=26; // 26个字母 /* *字典类 */ class Dictionary { private: vector<Word *>d; /* *哈希函数,将ch映射为索引号 */ int Hash(char ch) { ch=tolower(ch); return ch-'a'; } /* *比较单词one和other是否相等 */ bool cmp(string &one, string &other) { return one == other; } /* *根据索引号index来将p所指向的结点插入该链表的合适位置 *pre指向p的直接前驱 */ void Adjust(int index, Word *pre,Word *p) { if(!pre) return; //p指向链表的第一个结点 Word *cur=d[index]; //指向当前结点 Word *q=NULL; //指向cur的直接前驱 while(cur && cur->freq>p->freq) { q=cur; cur=cur->next; } pre->next=p->next; //将p指向的结点删除 if(!q) { p->next=d[index]; d[index]=q; } else { p->next=cur; q->next=p; } } public: Dictionary() { int i; for(i=0;i<N;i++) d.push_back(NULL); } void Search(string word) { Word *p; int index=Hash(word[0]); if(index<0 || index>=N) { cout<<"参数有误,程序退出!"<<endl; exit(1); } p=d[index]; Word *pre=NULL; //指向p的直接前驱 while(p) { if(cmp(p->word,word)) { //找到要查找的单词 p->freq++; Adjust(index,pre,p); break; } pre=p; p=p->next; } if(!p) { //没有找到单词 Word *q; q=new Word; q->freq=1; q->word=word; q->next=0; if(pre) pre->next=q; //pre指向链表最后一个结点 else d[index]=q; //该链表为空 } } /* *查找兄弟单词 **/ void SearchSibling(string word) { int i; int index; Word *p,*pre; for(i=0;word[i];i++) { index=Hash(word[i]); if(index<0 || index>=N) { cout<<"参数有误,程序退出!"<<endl; exit(1); } pre=NULL; p=d[index]; while(p) { string one=p->word; string other=word; sort(one.begin(),one.end()); sort(other.begin(),other.end()); if(cmp(one,other)) { //找到要查找的单词 p->freq++; Adjust(index,pre,p); cout<<p->word<<endl; } pre=p; p=p->next; } } } void show() const { int i; Word *p; for(i=0;i<N;i++) { p=d[i]; while(p) { cout<<p->word<<":"<<p->freq<<" "; p=p->next; } cout<<endl; } } }; void main() { Dictionary dictionary; string word; cout<<"输入exit退出系统"<<endl; cin>>word; while(word!="exit") { dictionary.Search(word); cin>>word; } dictionary.show(); cout<<"输入要查找的单词:"; cin>>word; cout<<word<<"的兄弟单词是:"<<endl; dictionary.SearchSibling(word); }
四: 测试
作者:wangzhicheng2013 发表于2012-12-30 22:22:03 原文链接
阅读:0 评论:0 查看评论