• Set/Map


    此代码是再BST.hLinkedList.h上的二次封装,阅读前请先了解底层代码。

    Set

    • 基于链表的Set:Value是无序不重复的。
    • 基于BST的Set:Value是有序不重复的。

    节点结构

    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的二次封装所以和底层数据结构的节点相同。

    Map

    • Map:是由Key和Value组成的键值对,由Key映射其对应的值Value。
    • 基于链表的Map:Key是无序不重复的。
    • 基于BST的Map:Key是有序不重复的。

    节点结构

    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 + "
    ");
                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;
    }
    

    运行结果:
    在这里插入图片描述

    查询一本书有多少不重复的单词

    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;
    }
    

    运行结果:
    在这里插入图片描述

    时间复杂度分析

    Map

    在这里插入图片描述

    Set

    在这里插入图片描述

    代码清单

    Set.h

    #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
    

    BSTSet.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
    
    

    LinkedListSet.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
    

    Map.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
    

    LinkedListMap.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
    

    BSTMap.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
    
  • 相关阅读:
    CSS实现DIV水平自适应居中
    jQuery实现鼠标拖动改变Div高度
    Word2013创建目录
    raw,cow,qcow,qcow2镜像的比较
    Chrome浏览器官方下载地址
    OLE/COM 对象查看器 & OLE常用术语
    VmWare为Fedora虚拟机扩展磁盘
    Linux常用命令
    项目经理与客户沟通的宜与忌
    转 FileStream Read File
  • 原文地址:https://www.cnblogs.com/chengmf/p/12939262.html
Copyright © 2020-2023  润新知