統計出現次數最多的資料
題目描述:
給你上千萬或上億資料(有重複),統計其中出現次數最多的前N個數據。
分析:上千萬或上億的資料,現在的機器的記憶體應該能存下(也許可以,也許不可以)。所以考慮採用hash_map/搜尋二叉樹/紅黑樹等來進行統計次數。然後就是取出前N個出現次數最多的資料了。當然,也可以堆實現。
ok,此題與上題類似,最好的方法是用hash_map統計出現的次數,然後再借用堆找出出現次數最多的N個數據。不過,上一題統計搜尋引擎最熱門的查詢已經採用過hash表統計單詞出現的次數,特此,本題咱們改用紅黑樹取代之前的用hash表,來完成最初的統計,然後用堆更新,找出出現次數最多的前N個數據。
同時,正好個人此前用c && c++ 語言實現過紅黑樹,那麼,程式碼能借用就借用吧。
完整程式碼:
- //[email protected] zhouzhenren &&July
- //July、updated,2011.05.08.
- //題目描述:
- //上千萬或上億資料(有重複),統計其中出現次數最多的前N個數據
- //解決方案:
- //1、採用紅黑樹(本程式中有關紅黑樹的實現程式碼來源於@July)來進行統計次數。
- //2、然後遍歷整棵樹,同時採用最小堆更新前N個出現次數最多的資料。
- //宣告:版權所有,引用必須註明出處。
-
#define PARENT(i) (i)/2
- #define LEFT(i) 2*(i)
- #define RIGHT(i) 2*(i)+1
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- typedefenum rb_color{ RED, BLACK }RB_COLOR;
- typedefstruct rb_node
- {
- int key;
- int data;
- RB_COLOR color;
- struct rb_node* left;
-
struct
- struct rb_node* parent;
- }RB_NODE;
- RB_NODE* RB_CreatNode(int key, int data)
- {
- RB_NODE* node = (RB_NODE*)malloc(sizeof(RB_NODE));
- if (NULL == node)
- {
- printf("malloc error!");
- exit(-1);
- }
- node->key = key;
- node->data = data;
- node->color = RED;
- node->left = NULL;
- node->right = NULL;
- node->parent = NULL;
- return node;
- }
- /**
- * 左旋
- *
- * node right
- * / / ==> / /
- * a right node y
- * / / / /
- * b y a b
- */
- RB_NODE* RB_RotateLeft(RB_NODE* node, RB_NODE* root)
- {
- RB_NODE* right = node->right; // 指定指標指向 right<--node->right
- if ((node->right = right->left))
- right->left->parent = node; // 好比上面的註釋圖,node成為b的父母
- right->left = node; // node成為right的左孩子
- if ((right->parent = node->parent))
- {
- if (node == node->parent->right)
- node->parent->right = right;
- else
- node->parent->left = right;
- }
- else
- root = right;
- node->parent = right; //right成為node的父母
- return root;
- }
- /**
- * 右旋
- *
- * node left
- * / / / /
- * left y ==> a node
- * / / / /
- * a b b y
- */
- RB_NODE* RB_RotateRight(RB_NODE* node, RB_NODE* root)
- {
- RB_NODE* left = node->left;
- if ((node->left = left->right))
- left->right->parent = node;
- left->right = node;
- if ((left->parent = node->parent))
- {
- if (node == node->parent->right)
- node->parent->right = left;
- else
- node->parent->left = left;
- }
- else
- root = left;
- node->parent = left;
- return root;
- }
- /**
- * 紅黑樹的3種插入情況
- * 用z表示當前結點, p[z]表示父母、p[p[z]]表示祖父, y表示叔叔.
- */
- RB_NODE* RB_Insert_Rebalance(RB_NODE* node, RB_NODE* root)
- {
- RB_NODE *parent, *gparent, *uncle, *tmp; //父母p[z]、祖父p[p[z]]、叔叔y、臨時結點*tmp
- while ((parent = node->parent) && parent->color == RED)
- { // parent 為node的父母,且當父母的顏色為紅時
- gparent = parent->parent; // gparent為祖父
- if (parent == gparent->left) // 當祖父的左孩子即為父母時,其實上述幾行語句,無非就是理順孩子、父母、祖父的關係。
- {
- uncle = gparent->right; // 定義叔叔的概念,叔叔y就是父母的右孩子。
- if (uncle && uncle->color == RED) // 情況1:z的叔叔y是紅色的
- {
- uncle->color = BLACK; // 將叔叔結點y著為黑色
- parent->color = BLACK; // z的父母p[z]也著為黑色。解決z,p[z]都是紅色的問題。
- gparent->color = RED;
- node = gparent; // 將祖父當做新增結點z,指標z上移倆層,且著為紅色。
- // 上述情況1中,只考慮了z作為父母的右孩子的情況。
- }
- else// 情況2:z的叔叔y是黑色的,
- {
- if (parent->right == node) // 且z為右孩子
- {
- root = RB_RotateLeft(parent, root); // 左旋[結點z,與父母結點]
- tmp = parent;
- parent = node;
- node = tmp; // parent與node 互換角色
- }
- // 情況3:z的叔叔y是黑色的,此時z成為了左孩子。
- // 注意,1:情況3是由上述情況2變化而來的。
- // ......2:z的叔叔總是黑色的,否則就是情況1了。
- parent->color = BLACK; // z的父母p[z]著為黑色
- gparent->color = RED; // 原祖父結點著為紅色
- root = RB_RotateRight(gparent, root); // 右旋[結點z,與祖父結點]
- }
- }
- else
- {
- // 這部分是特別為情況1中,z作為左孩子情況,而寫的。
- uncle = gparent->left; // 祖父的左孩子作為叔叔結點。[原理還是與上部分一樣的]
- if (uncle && uncle->color == RED) // 情況1:z的叔叔y是紅色的
- {
- uncle->color = BLACK;
- parent->color = BLACK;
- gparent->color = RED;
- node = gparent; // 同上
- }
- else// 情況2:z的叔叔y是黑色的,
- {
- if (parent->left == node) // 且z為左孩子
- {
- root = RB_RotateRight(parent, root); // 以結點parent、root右旋
- tmp = parent;
- parent = node;
- node = tmp; // parent與node 互換角色
- }
- // 經過情況2的變化,成為了情況3.
- parent->color = BLACK;
- gparent->color = RED;
- root = RB_RotateLeft(gparent, root); // 以結點gparent和root左旋
- }
- }
- }
- root->color = BLACK; // 根結點,不論怎樣,都得置為黑色。
-
相關推薦
統計出現次數最多的資料
題目描述: 給你上千萬或上億資料(有重複),統計其中出現次數最多的前N個數據。 分析:上千萬或上億的資料,現在的機器的記憶體應該能存下(也許可以,也許不可以)。所以考慮採用hash_map/搜尋二叉樹/紅黑樹等來進行統計次數。然後就是取出前N個出現
Linux下統計出現次數最多的指定欄位值
假設桌面上有一個data.txt文字,內容如下: {id='xxx' info='xxx' kk='xxx' target='111111' dd='xxx'} {id='xxx' info='xxx' kk='xxx' target='777' dd='xxx'} {i
用hash_map統計出現次數最多的前N個URL
海量資料統計頻率最高詞彙的常規辦法之一是先通過一個hash函式處理資料然後取模N,拆分為N個小檔案,對每一個小檔案進行詞頻統計和排序處理,然後歸併N個小檔案取頻率最大的M個數。 關於hash_map和map的選擇使用有幾點注意的,hash_map是hash表的形式實
Js面試題(二)--js實現統計出現次數最多字符個數
round rip ont js面試 () jos 圖片 第一個字符 clas 話不多話,直接上圖 統計出現次數最多的字符是哪個? 1、當然首先想到的是循環這個字符···· 2、用for循環--第一次檢索到
上千萬或上億資料(有重複),統計其中出現次數最多的N個數據. C++實現
上千萬或上億的資料,現在的機器的記憶體應該能存下。所以考慮採用hash_map/搜尋二叉樹/紅黑樹等來進行統計次數。然後就是取出前N個出現次數最多的資料了,可以用第2題提到的堆機制完成。 #in
判斷一個字符串中出現次數最多的字符,統計這個次數
sdff BE 出現次數 div asd 遍歷 轉換成 arr str var str = ‘abaasdffggghhjjkkgfddsssss3444343‘; // 1.將字符串轉換成數組 var newArr = str.spl
返回(統計)一個列表中出現次數最多的元素
clas 列表 元素 center enter ax1 叠代器 orm {} 首先定義一個函數 函數內逐行依次解釋為: #定義一個函數def max1(lt): dict1 = {} #建立一個空字典 s = set(lt)
判斷一個字符串中出現次數最多的字符,並統計字數
spa bbbb aci light turn border java UNC ber \1 等於 (\w) var s = ‘aaabbbcccaaabbbaaabbbbbbbbbb‘; var a = s.split(‘‘); a.sort();
(ES6的“...“配合ES5‘’forEach‘’)前端面試之判斷一個字串中出現次數最多的字元,統計這個次數
// 判斷一個字串中出現次數最多的字元,統計這個次數 let str = 'aasdadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsdasjjhsghkafsagjkg
演算法--統計文字中出現次數最多的單詞(字典樹)
統計一個文字中,出現次數最多的單詞:單詞全部小寫,單詞與單詞之間以空格間隔 1.利用字典 key為單詞 value為單詞出現的次數 def mostString(): dict = {} fr = open('preprocessing.txt')
sort +awk+uniq 統計檔案中出現次數最多的前10個單詞
原文地址:http://blog.sina.com.cn/s/blog_5dce657a01012ddi.html 作者:小新 例項cat logt.log|sort -s -t '-' -k1n |awk '{print $1;}'|uniq -c|sort -k1nr|head
如何統計一本英文書(比如簡愛)中出現次數最多的前1000個單詞
如何統計一本書中出現最多的前1000個單詞,其實只要處理好新單詞的儲存,已經出現單詞個數的統計,和根據出現次數的排序,就基本完成了這個專案。 思路:1、從檔案中依次讀取一個個字元,如果是字母字元就放到一個字元陣列中,當讀取的字元是空格或者標點符號時,則已經讀取的字串視為一個單詞,將其儲存起來。&
js 判斷一個字串中出現次數最多的字元,統計其出現次數
js 判斷一個字串中出現次數最多的字元,統計其出現次數 var str = 'asdfssaaasasasasaa'; var json = {}; for (var i = 0; i < str.length; i++) { if(!json[str.charAt(i
js統計陣列中出現次數最多的元素
想來想去沒想出更好的解決方法。 思路就是在ana函式裡先遍歷一遍arr,維護一個數組newArr 用於將所有數值相同的放在陣列中的同一個塊內。另外一個數組unique 用於維護數值唯一,判斷當前的item是否已存在於newArr中。為了方便比較物件的數值相同,
判斷一個字串中出現次數最多的字元,統計這個次數
var str = 'asdfssaaasasasasaa'; var json = {}; for (var i = 0; i < str.length; i++) { if(!json[str.charAt(i)]){ json[str.cha
linux中sort(統計檔案中出現次數最多的前10個單詞)
例項 cat logt.log|sort -s -t '-' -k1n |awk '{print $1;}'|uniq -c|sort -k1nr|head -100 使用linux命令或者shell實現:檔案words存放英文單詞,格式為每行一個英文單詞
numpy 統計陣列每一行出現次數最多的數字
使用np.bincount()和np.argmax()函式來實現。 np.bincount()可以把陣列中出現的每個數字,當做index,數字出現的次數當做value來表示。 np.argmax()可以返回陣列中最大值的index。 所以經過變換,可以得到出現次數的最大值。
統計陣列中出現次數最多的元素並輸出
實驗過程中遇到一個實際問題:需要統計出10次計數的值中出現最多的一個數,比如輸入34 35 35 35 34 35 35 35 34 33 十個數,要求最終輸出35.如果出現兩個數同樣多,則輸出兩個元素中較小的那一個(也可以是較大的那一個,但是必須確定是其中一種)。 程式碼
海量日誌資料,找出出現次數最多的IP地址。
import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java
Java統計一篇文章中出現次數最多的漢字或英文單詞 又出現次數的統計
思想是用到了Map集合的鍵唯一性儲存漢字或者單詞,單詞的獲取通過正則獲取: 統計類: import java.util.ArrayList; import java.util.Map; import java.util.Set; import java.util.Tree