Mini English-Chinese dictionary v2.0

Source: Internet
Author: User
Tags delete key strcmp

Mini English-Chinese dictionary v2.0

The second version of English-Chinese dictionary by Mingspy

=====================================================================================

function

1. Support the query of English words with split characters.

2, improve the structure of the Trie node, using the list storage child node pointers.

3, the branch node more refined, divided into with key values and no key values of the two classes, for some branches can save a pointer.

4, the new design of the interface of the Trie node.

5, the new design Dictinoary interface.

6, support the translation of Chinese characters to English (provide and load the corresponding dictionary can)

7, added the Factory mode to store obsolete nodes, reduce memory requests and node construction.

Shortcomings

1, still put all the dictionary files into memory.

2, the character terminal, the interaction is not good.

3, the efficiency slightly reduced

4, other personnel to modify the underlying code some difficulties, not conducive to maintenance.

[Problems encountered and solutions]

1, after adding nodefactory, compile normal, but link times LNK2005 and LNK1169 error. Look for some reasons on the Internet, do not understand.

Think of a book that static member functions can not be virtual and inline, so the implementation of the function into the NodeFactroy.cpp.

2, ring Reference, produce n many errors. To use a function of nodefactory in Trie.h, the NodeFactory.h is included, resulting in

n error, do not know the cause at present. The solution is to just declare the function you want to use. such as extern void Deletefactorynode ();

3, the introduction of nodefactory to produce null pointer error. The reason is that in setchild () the node to be cleared is again added to the Nodefactory warehouse. This in

The node has been added to the nodefactory in insert (). The nodes in the nodefactory are first refactored, causing null pointers to be generated when the trie of the child nodes is destructor. Over here

There is no good solution for preventing multiple joins to nodefactory, and the timing of joining Nodefactory, and where to maintain the subtree of the trie subtree, which

Unfavorable to other people to maintain. The solution to this problem is to remove the setchild in the storage. Comment out,//savetrienode ()

MyMain.cpp

#include <iostream> #include <ctime> #include "Trie.h" #include "Dictionary.h" #include "NodeFactory.h" Include <memory> int main (void) {cout<< "Welcome to the Mini English-Chinese dictionary v2.0 by Mingspy" <<endl; cout<< "=====================================================" <<endl; Auto_ptr<dictionary> Pdic (New fuzzydict (new Fuzzytrie)); if (!) ( Pdic->loaddictionary (NULL))//if (!) ( Pdic->loaddictionary ("./test.dic")) {cout<< "Load dic error" <<endl; return-1;} pdic->run (); }

Trie.h

 /***************************************************** * The header file of the dictionary tree ****************************************** /#ifndef __mingspy_trie_hh__ #define __MINGSPY_TRIE_HH__ #include <iostream> #include <list> # Include <string> using namespace std; extern void Deletefactorynode (); Enum NodeType {branch,brecord,leaf}; Branch, branch with key and value, leaf struct record {record (const char * k, const char * v); Record (const record &); Record * operator = (const record &); BOOL operator = = (const record &); ~record () {//cout<<key<< "Deleted." <<endl; if (key) Delete key; if (Val) delete Val; } char * key; char * VAL; }; /* The parent node of the node of the dictionary */class trienode{public:virtual ~trienode () {//cout<<getch () << "Delete" <<endl;} Char getch () const {return ch;} void Setch (char c) {ch = c;} NodeType GetType () {return _type.} void SetType (NodeType type) {_type = type;} Virtual record * Getrecord () const = 0{RE Turn NULL;} virtual void SetRecord [record * r] {} virtual Trienode * getchild (int c) {return NULL;} virtual bool SetChild (char C, trienode * child ) {return true;}; Protected:char ch; The English characters for the current stage, such as A, B, C 、... NodeType _type; Node type Trienode (char c,nodetype type): Ch (c), _type (type)///version one of the initialization order is incorrect, not in the declared order of {}}; typedef list<trienode *> LISTTRIENODEP; /* Branch node with no record/class Listbrtrienode:public trienode{Public:listbrtrienode (char c, NodeType type = BRANCH): Trienode (C,type), CHILDL (NULL) {} virtual ~listbrtrienode () {clear (this);//template method//cout<< getch () << BRAN CH Deleted "<<endl; if (CHILDL) Delete Childl;s}//Get child node Trienode * getchild (int c); Set child nodes to add child nodes directly, do not process child nodes of sub nodes bool SetChild (char C, trienode * children); Record * Getrecord () const {return NULL;} void Setchildl (LISTTRIENODEP * l) {childl = l;} LISTTRIENODEP * GETCHILDL () {return CHILDL;} PROTECTED:LISTTRIENODEP * CHILDL; Deletes all down-hanging child nodes and the node itself virtual void Clear (Trienode * pnode); }; /* Leaf node */classLeaftrienode:public trienode{Public:leaftrienode (char c): Trienode (c, LEAF), re (NULL) {} leaftrienode (char c,const Char * k, const char * v): Trienode (C,leaf), Re (new record (K,V)) {} leaftrienode (char C, const record & R): Trienode (C, LEAF), Re (new record (R)) {} ~leaftrienode () {if (re) delete re;} Record * Getrecord () const {return re;} void Setrecord (record * r) {re = r;} Private:record * RE; }; /* With Value Branch node */class Bretrienode:public Listbrtrienode {public:bretrienode (char c): Listbrtrienode (C,brecord), Re (NULL) { Bretrienode (char C, record * R): Listbrtrienode (c, Brecord), Re (r) {} bretrienode (char c,const char * k, const char * v ): Listbrtrienode (C,brecord), Re (new record (K,V)) {} ~bretrienode () {if (re) delete re;} Record * Getrecord () const {return re;} void Setrecord (record * r) {re = r;} Private:record * RE; }; * * * Dictionary tree, manage all Trienode/class Trie {Public:trie (): Root (NULL), ncnt (0) {} virtual ~trie () {if (root) delete root; Deletefactorynode ();} Virtual TRienode * FIND (const char * key) const; Find the node where the word is located, if key is not a word return null virtual Trienode * FINDNODE (const char * key) const; Find the node where the word is located and find the key, that is, return the node virtual bool Insert (const char * key, const char * val);/Hang a word and its explanation virtual bool Modify (Con St char * key, const char * newval);//Modify a word, no concrete implementation protected:trienode * root; The root of the dictionary tree size_t ncnt; Statistics count, for the time being not used}; /* A dictionary tree with fuzzy Lookup, using the Factory method mode/class Fuzzytrie:public Trie {public:virtual ~fuzzytrie () {} void Fuzzysearch (const char * key, List<const record *> &retlist); Fuzzy Lookup Function Interface Template method mode private:/* Actual lookup implementation, recursive methods, can be changed to non-recursive/virtual void Fuzzyfindall (Trienode * tn, List<const REC Ord *> &retlist); }; #endif

NodeFactory.h

#ifndef __mingspy_nodefactory_hh__ #define __MINGSPY_NODEFACTORY_HH__ #include "Trie.h" * * Factory, Used to produce trienode using FactoryMethod * *//using namespace std; Class Nodefactory {public: ~nodefactory () {Deleteallnode ();} Static Bretrienode *getbretrienode (char); static Leaftrien Ode * Getleaftrienode (char); Static Listbrtrienode * Getlistbrtrienode (char); static void Savenode (Trienode * p); static void Deleteallnode (); Private:nodefactory () {} static List<trienode * > Trienoderepository; }; Bretrienode *getbretrienode (char); Leaftrienode *getleaftrienode (char); Listbrtrienode * Getlistbrtrienode (char); void Savetrienode (Trienode *); void Deletefactorynode (); #endif

Dictrionary.h

#ifndef __mingspy_dictinary_hh__ #define __MINGSPY_DICTINARY_HH__ #include "Trie.h" extern void Deletefactorynode (); /* The Simple Dictionary class uses the Adpter mode, encapsulates the Trie tree, transforms the Trie interface/class Dictionary {public:dictionary (Trie * Trie = NULL): _dic (Trie) {}//constructor, Required to pass in a pointer to a trie tree ~dictionary () {if (_dic) Delete _dic}//destructor dictionary tree (trie * _dic) virtual bool Loaddictionary (const C Har * dicnamepath = NULL); Mount a dictionary from a file virtual const record * FIND (const char * word); Find the Chinese interpretation of the word Trie * Getdic () {return _dic;}//returns the saved Trie structure virtual void run (); Private:trie * _DIC; }; * * Fuzzy query dictionary, Dictrionary subclass, added the function of fuzzy query/class Fuzzydict:public Dictionary {public:fuzzydict (Fuzzytrie * trie):D IC Tionary (trie) {}//constructor, requires the Trie tree ~fuzzydict () {} virtual void Fuzzyfind (const char * word, list<const record *&G) passed in a fuzzy query T & Retlist); Fuzzy query function void run (); Overrides the service function of the parent class, providing a fuzzy query function}; #endif

Trie.cpp

#include "Trie.h" #include "NodeFactory.h" Record::record (const char * k, const char * v) {if (k) {key = new char [Strl En (k) + 1]; memcpy (key, K, strlen (k) + 1); } if (v) {val = new char [strlen (v) + 1]; memcpy (Val, V, strlen (v) + 1);}} Record::record (const record & R) {if (R.key) {key = new char [strlen (R.key) + 1]; memcpy (key, R.key, strlen (R.key) + 1); } if (R.val) {val = new char [strlen (R.val) + 1]; memcpy (Val, R.val, strlen (r.val) + 1);} Record * Record::operator = (const record & R) {if (a = = &r) return this; if (r.key) {key = new char [strlen ( R.key) + 1]; memcpy (Key, R.key, strlen (R.key) + 1); } if (R.val) {val = new char [strlen (R.val) + 1]; memcpy (Val, R.val, strlen (r.val) + 1); BOOL Record::operator = = (Const record & R) {if (! Key | |!r.key) return to false; return!strcmp (Key, R.key); Trienode * Listbrtrienode::getchild (int c) {if (!childl | | | childl->size () = 0) return NULL; Listtrienodep::iterator it = ChIldl->begin (); for (; it!= childl->end (); it +) {if (*it)->getch () = = c) return *it; BOOL Listbrtrienode::setchild (char C, trienode * child) {if (!CHILDL) childl = new Listtrienodep;/* Clear existing subnodes/* * LISTTR Ienodep::iterator it = Childl->begin (); if (childl->size ()!= 0) {for (; it!= childl->end (); it +) {if ((*it)->getch () = = c) {Childl->erase (it ); Break }}//* Add a new subnode/childl->push_back (child); return true; /* Clears all child nodes, recursively implements/void Listbrtrienode::clear (Trienode * pnode) {if (Pnode->gettype () = LEAF) return; LISTTRIENODEP * Childs = (listbrtrienode*) pnode)->getchildl (); /*** There is a problem not deleting the branch's record ***/if (childs) {Trienode * p; while (Childs->size ()) {p = Childs->front (); childs->p Op_front (); Delete p; } Delete Childs; ((listbrtrienode*) pnode)-&GT;SETCHILDL (NULL); }/* Find a node */Trienode * TRIE::FIND (const char * key) const {if (!key | |!root) return NULL; Trienode * p = root; const char * k = key; /* Follow the key to Drill-down down/while (*k && p->gettype ()!= LEAF && ((Listbrtrienode *) p)->getchild (*k)) {p = ((Listbrtrienode *) p)->getchild (*K); K + +; }/* the end of the loop, either all keys have been found, or the node to reach the tree/if (P->gettype ()!= LEAF) {/* If there are any remaining words not retrieved, then the word does not exist; If the word has been found, but there is no explanation, it is not a word * * if (*k | |!) ( ((Listbrtrienode *) p)->getrecord ()) return NULL; else {/* to the child node, if the word still has characters not found, there is no such word */if (*k) return NULL; } Trienode * Trie::findnode (const char * key) const {if (!key | | |!root) return NULL; Trienode * p = root; const char * k = key; while (*k && p->gettype ()!= LEAF && ((Listbrtrienode *) p)->getchild (*k)) {p = (Listbrtrienode *) p)->getchild (*K); K + +; } if (*k) return NULL; return p; * * * Insert a WORD */bool Trie::insert (const char * key, const char * val) {if (!key | |!val) return FALSE; Trienode * p = root; const char * k = key; if (!) ( *k)) return false; if (!p) {p = root = new Listbrtrienode (0);} Trienode * q = RooT Trienode *tmp; /* Insert only key[0,n-2], that is, the last character special processing, so you can insert a leaf node at the last word. *////////////////////////while (* (k+1)) {///* If the current node is a branch, and there are corresponding child nodes, continue to look down/if (P->gettype ()!= LEAF && p->getchild (* k)) {q = p;///After moving a node/p = ((Listbrtrienode *) p)->getchild (*k++);} else break; /* Loop End State: 1, K to the last character, you should insert *k 2 at the sub node of P, K is not the last character, and p points to a leaf node, at which point P is converted to a branch, and then the *k on P's child nodes and the following character 3, P's child node do not exist *k characters , then all the subsequent inserts are inserted into P's child nodes. */////* If it is a leaf node, convert the leaf node to a branch node with a value, Case 3/if (*k && p->gettype () = = leaf) {/* get an alternate with recorded branch node/tmp = Getbretrie Node (P->getch ()); Tmp->setrecord (P->getrecord ()); P->setrecord (NULL); Set record pointer to null/* Save leaf node standby/savetrienode (p); ((Listbrtrienode *) q)->setchild (Tmp->getch (), TMP); p = ((Listbrtrienode *) q)->getchild (Tmp->getch ()); /* * Establish all subsequent branch nodes */while (* (k+1)) {(Listbrtrienode *) p)->setchild (*k, Getlistbrtrienode (*k)); q = p; p = (Listbrtrie Node *) p)->getchild (*k++); /* Insert the last character */if (P->gettype ()!= LEAF) {/* Get the node where the last character is located * * *Q = ((Listbrtrienode *) p)->getchild (*K); /* If not present, create a new leaf node/if (!q) {tmp = Getleaftrienode (*k); Tmp->setrecord (new Record (key, Val)); ((Listbrtrienode *) p)->setchild (*K,TMP); TMP = NULL; else {*/* if there is already a value that does not allow insertion, use the modify*/if (Q->getrecord ()) {cout << "Key has exits, using modify () to modify it!" <<endl; return false; }/* Must be a branch that does not have a worthy branch, converts it to a value, and then inserts a record/tmp = Getbretrienode (Q->getch ()); /* Copies the original child node */((Bretrienode *) tmp)-&GT;SETCHILDL ((Listbrtrienode *) q)-&GT;GETCHILDL ()); /* Set Records/Tmp->setrecord (new Record (key,val)); /* Clear the child node of the original branch//((Listbrtrienode *) q)-&GT;SETCHILDL (NULL); Savetrienode (q);//Keep the original branch node standby p->setchild (Tmp->getch (), TMP); Only the branch, and it is not worth the time to save the} else//If p is a leaf node, then convert it to the component Branch node. Using the substitution method, insert a branch {/* Get a spare branch node with records/tmp = Getbretrienode (P->getch ()); Tmp->setrecord (P->getrecord ()); p-> Setrecord (NULL); Clear the record of the leaf node/* Save leaf node standby/savetrienode (p); ((Listbrtrienode *) q)->setchild (Tmp->getch (), TMP); return true; } bool TriE::modify (const char * key, const char * newval) {return true;} void Fuzzytrie::fuzzysearch (const char * key, List<c Onst record *> &retlist) {Trienode * tn = Findnode (key); if (!TN) return; Fuzzyfindall (TN, retlist); } void Fuzzytrie::fuzzyfindall (Trienode * tn, list<const record *> &retlist) {if (!TN) return; if (tn->getr Ecord ()) Retlist.push_back ((Tn->getrecord ())); if (tn->gettype () = = LEAF) {return;} else {LISTTRIENODEP * childs = ((Listbrtrienode *) TN)-&GT;GETCHILDL (); if (! Childs | | Childs->size () = = 0) return; Listtrienodep::iterator it = Childs->begin (); for (; it!= childs->end (); it +) {Fuzzyfindall (*it, retlist);}} }  

//dictionary.cpp

#include "Dictionary.h" #include <fstream> * * * from the dictionary file load content to the trie tree/bool Dictionary::loaddictionary (const char * Dicnamepath) {/* Open dictionary file */const char * FilePath =null; if (! Dicnamepath) FilePath = "./foreigntrade.dic"; else Filepat h = dicnamepath; Ifstream inf (filepath,ios::in); if (Inf.fail ()) {cout<< "open" << inf << "Failed" <<endl; return false;/* Ensure that the dictionary tree has been instantiated/if (!_ DIC) {_dic = new Trie;} char buf[1024]; char * p/*, *q*/; /* Read the contents of the file and load it into memory (hang to the dictionary tree)/while (!inf.eof ()) {memset (buf, 0, sizeof (BUF)); Inf.getline (buf, 1024);//cout<<buf< <endl; if (buf[0] = = ' @ ') continue; p = strchr (buf, '/t '); if (!p) {continue;} *p++ = '/0 '; /* support other character q=buf; while (*q && isalpha (*q)) {q++;} if (*q) continue; * * _dic->insert (BUF,P); Hang to Tree} inf.close (); Deletefactorynode (); return true; /* Find a Word/const record * DICTIONARY::FIND (const char * word) {if (!word) return NULL; if (!_dic) {cout<< "Please install first Load the dictionary. "<<endl; ReturnNULL; //Find the node that stores the word Trienode * tn =_dic->find (word); Returns the Chinese explanation of the word if (!TN) return NULL; else return Tn->getrecord (); } * * provides query dictionary functionality/void Dictionary::run () {if (!_dic) {cout<<) please load dictionary first. "<<endl; return; } Char key[100]; memset (key, 0, sizeof (key)); cout<< "Input the word u want to find:"; cin>>key; Const RECORD * RET; while (Key[0]!= ' # ') {ret = find (key), if (!ret) {cout<< key << ' not found in ' dictionary L else {cout<<key<< "/t" <<ret->val<<endl;} memset (key, 0, sizeof (key)); cout<< "Input the word u want to find:"; cin>>key; }/* Fuzzy query. For word that you enter, all words that begin with the query are */void Fuzzydict::fuzzyfind (const char * word, List<const record *> & retlist) {if!ge Tdic ()) {cout<<] Please load the dictionary first. "<<endl; return; }/* * Fit the Trie tree's fuzzy query, the trie tree's fuzzy query implementation of the specific content/((fuzzytrie*) getdic ())->fuzzysearch (Word, retlist); * * Provide fuzzy query function/void Fuzzydict::run () {if (!getdic ()) {cout<< "Please load firstDictionary. "<<endl; return; } Char key[100]; memset (key, 0, sizeof (key)); cout<< "Input the word u want to find:"; cin>>key; Const RECORD * RET; while (Key[0]!= ' # ') {ret = find (key), if (!ret) {/* not found, ask if the fuzzy query/cout<< key << "not found in the DI ctionary./n "<<" Do you want the fuzzy find "<< key <<"?/n "<<"/t/tyes,to Fuzzy find./n "<<"/t/tn O,to a new find./n "<<"/t/t#,to Quit "<<endl; Char cmd[20]; memset (cmd, 0, sizeof (CMD)); cin>> cmd; if (cmd[0] = = ' # ') return; if (!strcmp (cmd, "yes")) {/* Get all the results of a fuzzy query * */list<const record *> wordlist; Fuzzyfind (key, wordlist); /* Print result */if (!wordlist.size ()) {cout<< "No relatived Word to [<<key<<]." <<endl; else{cout<< "relatived word to [<<key<<]:" <<endl; For (List<const record *>::iterator it = Wordlist.begin (); it!= wordlist.end (); it + +) {cout << "T" << ( *it)->key<< "/t" << (*it)->val<<endl; }} else if (strcmp (cmd, "no") {cout<< "Bad command!") <<endl; } else {cout<<key<< '/t ' <<ret->val<<endl;} memset (key, 0, sizeof (key)); cout<< "Input the word u want to find:"; cin>>key; }}  

NodeFactory.cpp

#include "NodeFactory.h" Bretrienode *nodefactory::getbretrienode (char c) {Trienode * p = NULL; Listtrienodep::iterator it = Trienoderepository.begin (); for (; it!= trienoderepository.end (); it +) {if (*it)->gettype () = = Brecord) {p = *it; Trienoderepository.erase (i T); Break } if (p) P->setch (c); else P = new Bretrienode (c); Return (Bretrienode *) p; } Leaftrienode * Nodefactory::getleaftrienode (char c) {Trienode * p = NULL; Listtrienodep::iterator it = Trienoderepository.begin (); for (; it!= trienoderepository.end (); it +) {if (*it)->gettype () = = LEAF) {p = *it; trienoderepository.erase (IT); Break } if (p) P->setch (c); else P = new Leaftrienode (c); Return (Leaftrienode *) p; } Listbrtrienode * Nodefactory::getlistbrtrienode (char c) {Trienode * p = NULL; Listtrienodep::iterator it = Trienoderepository.begin (); for (; it!= trienoderepository.end (); it +) {if (*it)->gettype () = = BRANCH) {p = *it; Trienoderepository.erase (it ); Break } if (p) p-&Gt;setch (c); else P = new Listbrtrienode (c); Return (Listbrtrienode *) p; } void Nodefactory::savenode (Trienode * p) {trienoderepository.push_back (P);} void Nodefactory::D eleteallnode () {LISTT Rienodep::iterator it = Trienoderepository.begin (); if (trienoderepository.size ()!= 0) {Trienode * p; while (!trienoderepository.empty ()) {p = Trienoderepository.front () ; Trienoderepository.pop_front (); Delete p; }} List<trienode * > nodefactory::trienoderepository; Bretrienode *getbretrienode (char c) {return Nodefactory::getbretrienode (c);} Leaftrienode *getleaftrienode (char c) {return Nodefactory::getleaftrienode (c);} Listbrtrienode * Getlistbrtrienode (char c) {return Nodefactory::getlistbrtrienode (c);} void Savetrienode (Trienode * p) { Nodefactory::savenode (P); } void Deletefactorynode () {nodefactory::D eleteallnode ();}  

Test.dic

@ Foreign Trade Words AB N. shortened, abbreviated ABC N. Suspend, suspend A-BC v. haha genius genius

Description

The format of the dictionary content is a single row of records. The format of the record is divided into words and explanations with a table character. Such as

Word 1TABLE explanation 1

Word 2TABLE explanation 2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.