C + + implements counter in the Python standard library

Source: Internet
Author: User
Tags prev

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&LT;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-&GT;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

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.