Look at the Python standard library by Exmple, which mentions a counter container, which, like Muliset, can maintain a set, insert elements in a constant time, query the number of elements, and also provide a
The Most_common (n) method is used to count the largest n elements of the frequency, which is useful when reading text and counting the word frequency.
When considering the implementation of C + +, we find something called Lfu, https://en.wikipedia.org/wiki/Least_frequently_used, about the disk caching strategy, and the basic idea is similar to this counter.
Http://dhruvbird.com/lfu.pdf There are related implementations here.
#include <iostream> #include <list> #include <vector> #include <unordered_map>using namespace std;//key byte point template<typename t>struct keynode{typedef T Value_type;keynode () {}keynode (T V, keyNode* p, keyNode* n ): Val (v), prev (p), next (n) {}t val;keynode* prev;keynode* next;};/ /Counter node Template<typename t>struct countnode{countnode () {keyhead = new keynode<t>; Keyhead->prev = Keyhead->next = NULL;} ~countnode () {while (Keyhead->next! = NULL) {keynode<t>* p = Keyhead->next;keyhead->next = p->next; Delete p;} Delete Keyhead;} Countnode (int f, countnode* p, Countnode *n): Freq (f), Prev (p), next (n) {keyhead = new Keynode<t>;keyhead->prev = Keyhead->next = NULL;} keynode<t>* Insertkey (const t& v) {keynode<t>* node = new Keynode<t> (V, Keyhead, Keyhead->next) ; if (keyhead->next! = NULL) Keyhead->next->prev = Node;keyhead->next = Node;return node;} int freq;keynode<t>* keyhead;countnode* prev;countnode* next;};/ /Counter container/*** supports the following actions: Insert Time complexity O (1) Find (lookup) time complexity O (1) query the most frequent n elements (Most_common (n)) time complexity O (n) Delete operation time complexity O (1) **/ Template<typename T>class Counter{public:counter () {head = new countnode<t> (0, NULL, NULL); tail = null;} ~counter () {while (Head->next! = NULL) {countnode<t>* p = head->next;head->next = P->next;delete p;} Delete Head;} Insert a keyword if it already exists, frequency plus 1void insert (const t& v) {if (Dict.find (v) = = Dict.end ()) {//keyword is the newly inserted if (Head->next = = NULL | | h Ead->next->freq! = 1) {//need to create new count nodes countnode<t>* node = new countnode<t> (1, head, head->next); if ( Head->next = = NULL) Tail = Node;head->next = Node;dict[v] = pair<countnode<t>*, keynode<t>*> ( node, Node->insertkey (v));} ELSE{DICT[V] = pair<countnode<t>*, keynode<t>*> (Head->next, Head->next->insertkey (v));}} else{//keyword already exists//frequency will inevitably increase, at this time the change of the structure is larger countnode<t>* countaddr = dict[v].first;countnode<t>* Nextcount = countaddr->next; Keynode<t>* keyaddr = dict[v].second;int freq = countaddr->freq;//Remove a countaddr node from keyaddr first keyaddr->prev- >next = Keyaddr->next;if (keyaddr->next! = NULL) Keyaddr->next->prev = Keyaddr->prev;delete keyAddr; if (Nextcount = = NULL | | Nextcount->freq! = freq + 1) {//need to add a countnode node countnode<t>* node = new COUNTNODE<T&G t; (Freq + 1, countaddr, nextcount); if (nextcount! = NULL) Nextcount->prev = Node;elsetail = Node;countaddr->next = no DE;DICT[V] = pair<countnode<t>*, keynode<t>*> (node, Node->insertkey (v));} ELSE{DICT[V] = pair<countnode<t>*, keynode<t>*> (Nextcount, Nextcount->insertkey (v));} If the deleted Keynode node is the last Keynode in Countnode, it is necessary to remove the COUNTADDR also if (Countaddr->keyhead->next = = NULL) {countaddr-> Prev->next = Countaddr->next;if (countaddr->next! = NULL) Countaddr->next->prev = countAddr->prev; Delete countaddr;}}} Returns the frequency of the keyword int lookup (const t& v) Const{return dict[v].first->freq;} /** returnThe return frequency of the highest n elements returns in the form of: (Key,count) **/vector<pair<t, int>> most_common (int n) {//list order is frequency from low to high, At this point, you need to reverse-traverse n elements from the tail node vector<pair<t, int>> result;countnode<t>* countvisitor = tail;while (n > 0 && Amp Countvisitor = NULL) {keynode<t>* keyvisitor = countvisitor->keyhead->next;while (n > 0 && Keyvisitor = NULL) {result.emplace_back (keyvisitor->val, countvisitor->freq); n--;keyvisitor = keyVisitor-> Next;} Countvisitor = Countvisitor->prev;} return result;} Vector<pair<t, int>> least_common (int n) {vector<pair<t, int>> result;countnode<t>* Countvisitor = head->next;while (n > 0 && countvisitor! = NULL) {keynode<t>* keyvisitor = Countvisitor ->keyhead->next;while (n > 0 && keyvisitor! = NULL) {result.emplace_back (Keyvisitor->val, COUNTVISITOR->FREQ); n--;keyvisitor = Keyvisitor->next;} Countvisitor = Countvisitor->next;} return result;} private:countnode<t>* Head; countnode<t>* tail;unordered_map<t, pair<countnode<t>*, keynode<t>*>> dict;}; int main () {{counter<char> wordcount;string s ("Jfoaedfrerlkmgvj9ejajiokl;fdaks"); for (auto v:s) { Wordcount.insert (v);} Auto result = Wordcount.least_common (3);} return 0;}
C + + implements counter in the Python standard library