此代碼是再BST.h和LinkedList.h上的二次封裝,閱讀前請先了解底層代碼。html
template<typename T> class BSTNode{ public: T e; //節點元素 BSTNode<T>*left; //左節點 BSTNode<T>*right; //右節點 public: BSTNode(T E):e(E),left(nullptr),right(nullptr){} //初始化 };
template<typename T> class Node { public: T e; Node<T>*next; public: Node():e(0),next(nullptr){} Node(T& E):e(E),next(nullptr){} Node(T& E,Node<T>*Next):e(E),next(Next){} };
因爲是底層鏈表和BST的二次封裝因此和底層數據結構的節點相同。node
template<typename K,typename V> class MapNode{ public: K key; V value; MapNode<K,V>*next; public: MapNode():key(),value(),next(nullptr){} MapNode(K KEY,V VALUE,MapNode<K,V>*NEXT):key(KEY),value(VALUE),next(NEXT){} };
template<typename K,typename V> class BSTNode{ public: K key; V value; BSTNode<K,V>*left,*right; public: BSTNode(K key,V value):key(key),value(value),left(nullptr),right(nullptr){} BSTNode(BSTNode<K,V>*node):key(node->key),value(node->value),left(node->left),right(node->right){} };
#ifndef C___FILEOPERATION_H #define C___FILEOPERATION_H #include <string> #include <iostream> #include <fstream> #include <vector> #include <cassert> using namespace std; namespace FileOps { bool isCharacter(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } int firstCharacterIndex(const string &s, int start) { for (int i = start; i < s.length(); i++) if (isCharacter(s[i])) return i; return s.length(); } string lowerS(const string &s) { string ret = ""; for (int i = 0; i < s.length(); i++) { assert(isCharacter(s[i])); ret += tolower(s[i]); } return ret; } bool readFile(const string &filename, vector<string> &words) { string line; string contents = ""; ifstream file(filename); if (file.is_open()) { while (getline(file, line)) contents += (line + "\n"); file.close(); } else { cout << "Can not open " << filename << " !!!" << endl; return false; } int start = firstCharacterIndex(contents, 0); int i; for (i = start + 1; i <= contents.length();) { if (i == contents.length() || !isalpha(contents[i])) { words.push_back(lowerS(contents.substr(start, i - start))); start = firstCharacterIndex(contents, i); i = start + 1; } else { i++; } } return true; } } #endif //C___FILEOPERATION_H
int main() { std::cout << "a-tale-of-two-cities.txt" << std::endl; vector<string> words; if (FileOps::readFile(".././a-tale-of-two-cities.txt", words)) { std::cout << "Total words: " << words.size() << std::endl; BSTSet<string> *bstSet = new BSTSet<string>(); for(string word : words) { bstSet->add(word); } std::cout << "Total different words: " << bstSet->getSize() << std::endl; bstSet = nullptr; delete bstSet; } std::cout << "pride-and-prejudice.txt" << std::endl; vector<string> words1; if (FileOps::readFile(".././pride-and-prejudice.txt", words1)) { std::cout << "Total words: " << words1.size() << std::endl; BSTSet<string> *bstSet = new BSTSet<string>(); for(string word : words1) { bstSet->add(word); } std::cout << "Total different words: " << bstSet->getSize() << std::endl; bstSet = nullptr; delete bstSet; } return 0; }
運行結果:
ios
int main() { std::cout << "a-tale-of-two-cities.txt" << std::endl; string filename = ".././a-tale-of-two-cities.txt"; BSTMap<string, int> *bstMap = new BSTMap<string, int>(); vector<string> words; if (FileOps::readFile(filename, words)) { std::cout << "Total words: " << words.size() << std::endl; for (string word : words) { if (bstMap->contains(word)) { bstMap->set(word, *(bstMap->get(word)) + 1); } else { bstMap->add(word, 1); } } std::cout << "Total different words: " << bstMap->getSize() << std::endl; std::cout << "Frequency of PRIDE: " << *(bstMap->get("pride")) << std::endl; std::cout << "Frequency of PREJUDICE: " << *(bstMap->get("prejudice")) << std::endl; } return 0; }
運行結果:
數據結構
#ifndef C___SET_H #define C___SET_H template<typename T> class Set { virtual void add(T e) = 0; virtual void remove(T e) = 0; virtual bool contains(T e)const= 0; virtual int getSize()const= 0; virtual bool isEmpty()const= 0; }; #endif //C___SET_H
#ifndef C___BSTSET_H #define C___BSTSET_H #include "Set.h" #include "BST.h" template<typename T> class BSTSet: public Set<T> { private: BST<T>*bst; public: BSTSet(){ new BSTSet<T>(); } int getSize()const{ return bst->getSize(); } bool isEmpty()const{ return bst->isEmpty(); } void add(T e){ bst->add(e); } void remove(T e){ bst->RRemove(e); } bool contains(T e)const { return bst->contains(e); } ~BSTSet(){ delete bst; } }; #endif //C___BSTSET_H
#ifndef C___LINKEDLISTSET_H #define C___LINKEDLISTSET_H #include "LinkedList.h" #include "Set.h" template<typename T> class LinkedListSet: public Set<T> { private: LinkedList<T>*list; public: LinkedListSet(){ list = new LinkedList<T>(); } int getSize()const{ return list->getSize(); } bool isEmpty()const { return list->isEmpty(); } bool contains(T e)const { return list->contains(e); } void add(T e){ if(!list->contains(e)){ list->addFirst(e); } } void remove(T e){ list->removeElement(e); } ~LinkedListSet(){ delete list; } }; #endif //C___LINKEDLISTSET_H
#ifndef C___MAP_H #define C___MAP_H template<typename K,typename V> class Map { virtual int getSize()const = 0; virtual bool isEmpty()const = 0; virtual bool contains(K key) = 0; virtual void add(K key,V value) = 0; virtual V* get(K key) = 0; virtual void set(K key,V value) = 0; virtual V* remove(K key) = 0; }; #endif //C___MAP_H
// // Created by cmf on 2020/5/19. // #ifndef C___LINKEDLISTMAP_H #define C___LINKEDLISTMAP_H #include "Map.h" template<typename K,typename V> class MapNode{ public: K key; V value; MapNode<K,V>*next; public: MapNode():key(),value(),next(nullptr){} MapNode(K KEY,V VALUE,MapNode<K,V>*NEXT):key(KEY),value(VALUE),next(NEXT){} }; template<typename K,typename V> class LinkedListMap : public Map<K,V>{ private: MapNode<K,V>*dummyHead; int size; MapNode<K,V>* getNode(K key){ MapNode<K,V>*cur = dummyHead->next; while(cur!= nullptr){ if(cur->key == key){ return cur; } cur = cur->next; } return nullptr; } public: LinkedListMap():size(0){ dummyHead = new MapNode<K,V>(); } int getSize()const{ return size; } bool isEmpty()const { return size == 0; } bool contains(K key) { return getNode(key)!= nullptr; } V get(K key){ if(contains(key) == true){ MapNode<K,V>*node = getNode(key); return node->value; } } void set(K key,V value){ MapNode<K,V>*node = getNode(key); if(node== nullptr){ add(key,value); }else{ node->value = value; } } void add(K key,V value){ MapNode<K,V>*node = getNode(key); if(node == nullptr){ dummyHead->next = new MapNode<K,V>(key,value,dummyHead->next); ++size; }else{ node->value = value; } } V remove(K key){ MapNode<K,V>*prev = dummyHead; while(prev->next!= nullptr){ if(prev->next->key == key){ break; } prev = prev->next; } if(prev->next!= nullptr){ MapNode<K,V>*delNode = prev->next; prev->next = delNode->next; delNode->next = nullptr; --size; return delNode->value; }else{ return prev->value; } } }; #endif //C___LINKEDLISTMAP_H
#ifndef C___BSTMAP_H #define C___BSTMAP_H #include "Map.h" template<typename K,typename V> class BSTNode{ public: K key; V value; BSTNode<K,V>*left,*right; BSTNode(K key,V value):key(key),value(value),left(nullptr),right(nullptr){} BSTNode(BSTNode<K,V>*node):key(node->key),value(node->value),left(node->left),right(node->right){} }; template<typename K,typename V> class BSTMap :public Map<K,V>{ private: BSTNode<K,V>*root; int size; public: int getSize()const{ return size; } bool isEmpty()const{ return size == 0; } BSTNode<K,V>*getNode(BSTNode<K,V>*node,K key){ if(node == nullptr){ return nullptr; } if(node->key == key){ return node; }else if(node->key<key){ return getNode(node->left,key); }else{ return getNode(node->right,key); } } bool contains(K key){ return getNode(root,key)!= nullptr; } void add(K key,V value){ root = add(root,key,value); } V *get(K key) { BSTNode<K,V> *node = getNode(root, key); return node == nullptr ? nullptr : &(node->value); } void set(K key,V value){ BSTNode<K,V>*node = getNode(root,key); if(node!= nullptr){ node->value = value; } } V* remove(K key){ BSTNode<K,V>*node = getNode(root,key); if(node!= nullptr){ root = remove(root,key); return &(node->value); } return nullptr; } ~BSTMap(){ destory(root); } BSTNode<K,V>* min(BSTNode<K,V>*node){ if(node->left == nullptr){ return node; } min(node->left); } BSTNode<K,V>* max(BSTNode<K,V>*node){ if(node->right == nullptr){ return node; } min(node->right); } BSTNode<K,V> *removeMin(BSTNode<K,V> *node) { if(node->left == nullptr){ BSTNode<K,V>*rightNode = node->right; delete node; --size; } node->left = removeMin(node->left); return node; } BSTNode<K,V> *removeMax(BSTNode<K,V> *node) { if(node->right == nullptr){ BSTNode<K,V>*rightNode = node->left; delete node; --size; } node->right = removeMin(node->right); return node; } private: BSTNode<K,V>* add(BSTNode<K,V>*node,K key,V value){ if(node == nullptr){ ++size; return new BSTNode<K,V>(key,value); } if(key == node->key){ node->value = node->value; }else if(key < node->key){ node->left = add(node->left,key,value); }else{ node->right = add(node->right,key,value); } return node; } void destory(BSTNode<K,V>*node){ if(node!= nullptr){ destory(node->left); destory(node->right); delete node; --size; } } BSTNode<K,V>*remove(BSTNode<K,V>*node,K key){ if(node == nullptr){ return nullptr; } if(node->key>key){ node->left = remove(node->left,key); return node; }else if(node->key<key){ node->right = remove(node->right,key); return node; }else { if (node->left == nullptr) { BSTNode<K, V> *rightNode = node->right; delete node; --size; return rightNode; } if (node->right == nullptr) { BSTNode<K, V> *leftNode = node->left; delete node; --size; return leftNode; } BSTNode<K, V> *succcessor = new BSTNode<K, V>(min(node->right)); //Node *precursor = new Node(maximum(node->right)); succcessor->right = removeMin(node->right); succcessor->left = node->left; //precursor->left = removeMax(node->left); //precursor->right = node->right; node->left = node->right = nullptr; delete node; return succcessor; //return precursor; } } }; #endif //C___BSTMAP_H