- 论坛徽章:
- 1
|
原帖由 2eye 于 2006-8-21 13:10 发表
昨晚看到这个题目,用C++写了一个,结果比人家java写的跑得还慢!请教高手如何很好的完成这个任务:
感觉关键就是hash函数
- #include <cstddef>
- #include <iostream>
- #include <fstream>
- #include <list>
- #include <iterator>
- #include <map>
- using namespace std;
- struct WordNode
- {
- string word;
- WordNode *pre_word, *pre_match, *pre_node, *next_node;
- bool first_match;
- WordNode() : pre_word(NULL), pre_match(NULL), pre_node(NULL), next_node(NULL), first_match(true) { }
- ~WordNode() { }
- };
- bool MatchWord(const WordNode *first, const WordNode *second, int M)
- {
- const WordNode *ptr = second;
- for(int i=0; i<M; i++) {
- if(first->word != second->word || first == ptr) return false;
- first = first->next_node;
- second = second->next_node;
- }
- return true;
- }
- int hashfunc(WordNode *node, int M)
- {
- unsigned short v = 0;
- for(int i=0; i<M && node != NULL; i++) {
- for(int j=0; j<node->word.size(); j++)
- v = 5*v + node->word[j];
- node = node->next_node;
- }
- return int(v);
- }
- int main()
- {
- ifstream inf("words.txt");
- if (!inf) {
- cerr << "Error open file words.txt" << endl;
- exit(-1);
- }
- WordNode *head, *node, *tail = NULL, *ptr, *match;
- int M, N, i=0, cnt;
- cin >> M >> N;
- WordNode **preM = new WordNode*[M];
- int index=0;
- memset(preM, 0, sizeof(WordNode*) * M);
- node = new WordNode;
- head = node;
- map<int, WordNode *> wordMap;
- map<int, WordNode *>::iterator map_itr;
- int hashval;
- while(inf >> node->word) {
- preM[index] = node;
- index = (index+1)%M;
- ptr = preM[index];
- hashval = hashfunc(ptr, M);
- if(hashval > 0) {
- if((map_itr = wordMap.find(hashval)) == wordMap.end()) {
- wordMap[hashval] = node;
- }
- else {
- node->pre_word = map_itr->second;
- map_itr->second = node;
- }
- }
- if(ptr != NULL) {
- for(match=ptr->pre_word; match != NULL; match = match->pre_word) {
- if(MatchWord(match, ptr, M)) {
- ptr->pre_match = match;
- match->first_match = false;
- break;
- }
- }
- }
- tail = node;
- node = new WordNode;
- tail->next_node = node;
- node->pre_node = tail;
- }
- list<pair<WordNode *, int> > toplist;
- list<pair<WordNode *, int> >::iterator itr;
- for(; ptr != NULL; ptr=ptr->pre_node) {
- if(ptr->first_match) {
- cnt = 1;
- for(match = ptr->pre_match; match != NULL; match = match->pre_match) cnt++;
- for(itr=toplist.begin(); itr!=toplist.end() && itr->second > cnt; ++itr);
- if(itr!=toplist.end()) {
- toplist.insert(itr, make_pair(ptr, cnt));
- if(toplist.size() > N)
- toplist.pop_back();
- }
- else if(toplist.size() < N)
- toplist.push_back(make_pair(ptr, cnt));
- }
- }
- for(itr=toplist.begin(), i=1; itr!=toplist.end(); ++itr, i++) {
- cout << "No." << i << ":";
- ptr = itr->first;
- for(int j=0; j<M; j++, ptr=ptr->next_node) {
- cout << ptr->word << " ";
- }
- cout << endl << "Count:" << itr->second << endl;
- }
- while(head != NULL) {
- ptr = head->next_node;
- delete head;
- head = ptr;
- }
- }
复制代码 |
|