1. 程式人生 > >從十億資料中找出出現最多的數以及出現次數

從十億資料中找出出現最多的數以及出現次數

package org.example.bigdata;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class TopTimes {
	public static void main(String[] args) {
		final int input[] = {2389,8922,3382,6982,5231,8934,8923,7593
							,4322,7922,6892,5224,4829,3829,8934,8922
							,6892,6872,4682,6723,8923,3492,9527,8923
							,7593,7698,7593,7593,7593,8922,9527,4322
							,8934,4322,3382,5231,5231,4682,9527,9527};
		
		int sort[] = new int[1000];
		//Set all bit to 0
		for(int index = 0; index < sort.length; index++){
			sort[index] = 0;
		}
		Map<Integer,Integer> numCountMap = new HashMap<Integer,Integer>();
		for(int number : input){
			//Every number takes 2 bit.
			int existTimes = (sort[number >>> 4] >>> (2 * (number % 16))) & (1 | 1 << 1);
			//Increase counter in sort array.
			if(existTimes <= ((1 | 1 << 1) - 1)){
				existTimes++;
				//set two bit zero
				sort[number >>> 4] &= ~((1 | 1 << 1) << (2 * (number % 16)));
				//set increased bit value
				sort[number >>> 4] |= existTimes << (2 * (number % 16));
				//set <number, counter> into two maps.
				if((1 | 1 << 1) == existTimes){
					numCountMap.put(number, existTimes);
				}
			}
			else{
				//Time >= 3, increase the counter in treemap.
				if((1 | 1 << 1) == existTimes){
					int mapCounter = numCountMap.get(number).intValue();
					mapCounter++;
					numCountMap.put(number, mapCounter);
				}
			}
		}

		List<CounterNumber> counterList = new LinkedList<CounterNumber>();
		for(Integer number : numCountMap.keySet()){
			counterList.add(new CounterNumber(numCountMap.get(number), number));
		}
		Collections.sort(counterList);
		for(CounterNumber counterNumber : counterList){
			System.out.println(counterNumber.getCounter() + "----" + counterNumber.getNumber());
		}
	}
}

class CounterNumber implements Comparable<CounterNumber>{
	private Integer counter;
	private Integer number;
	public CounterNumber(Integer counter, Integer number){
		this.counter = counter;
		this.number  = number;
	}
	
	public Integer getCounter(){
		return this.counter;
	}
	public Integer getNumber(){
		return this.number;
	}
	@Override
	public int compareTo(CounterNumber counterNumber){
		return counterNumber.getCounter().compareTo(this.getCounter());
	}
}

大體思路和上一篇《從十億資料找出最大的一百個數》差不多,不過原來1-Bit表示一個數,擴充套件為2^N位數來儲存一個數出現次數,當出現次數超過2^N-1次時,把資料放入一個Map中。

根據長尾效應,排名靠前的數字出現次數很大,後面的數字劇減。某業務實際生產環境中,一億條資料取Top一萬的記錄,排名第一的出現400萬次,排名第10000位的出現不足5000次。

演算法中是以數字來計算的,但是位於文字記錄也有意義,可以將文字逐條計算出HashCode,再使用該演算法。同時對Map/CounterNumber也進行相應的改造,加入原始文字欄位。

相關推薦

資料出現多的數以及出現次數

package org.example.bigdata; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List

演算法-數字大的一萬個--9-3

十億的資料量    4G記憶體空間 1.建陣列  迴圈一萬次 找出最大的一萬個   複雜度o(n*m) n為10億  m為1萬 2.藉助快速排序    複雜度o(nlogn) 3.不想放入記憶體 佔據如此大的空間 建一個長度為1萬的陣列    將前1萬個數字放入陣列   其

如何大量資料異常值

前言 機器學習中資料預處理階段,首先要考慮的就是將資料集中的異常值找出來,然後再做額外處理。當然,異常值的處理並不存在什麼銀彈,只能具體情況具體分析再根據效果選擇處理方法。 直方圖 看看資料集直方圖也許能看出點端倪,比如下面這個圖,下方的是原始資料集,上面的是對應直方圖,可以看到大多數都分佈在11000

個ip出現次數多的IP(分治法)

/* 1,hash雜湊 2,找到每個塊出現次數最多的(默認出現均勻)—–>可以用字典樹 3,在每個塊出現最多的資料中挑選出最大的為結果 */ 問題一: 怎麼在海量資料中找出重複次數最多的一個 演算法思想: 方

[面試題]海量資料處理-10個數頻率最高的1000個數

方法一:分治思想 通常比較好的方案是分治+Trie樹/hash+小頂堆(就是上面提到的最小堆),即先將資料集按照Hash方法分解成多個小資料集,然後使用Trie樹或者Hash統計每個小資料集中的que

TOP-K排序演算法,海量不重複資料大/小的K個數

如題,TOP-K排序的主要功能是找出一堆不重複資料中的最小或最大的幾個數,此處我們介紹這種型別題目的某種解法: 最大最小堆,最大堆結構裡面的每一個數不都是小於root的值麼?和我們要解決的問題很像。由此,我們可以構造一個堆,並且用它來儲存我們需要找的那幾個數。有這麼一個動態

怎樣10查詢詞出現頻率最高的10個

1. 問題描述 在大規模資料處理中,常遇到的一類問題是,在海量資料中找出出現頻率最高的前K個數,或者從海量資料中找出最大的前K個數,這類問題通常稱為“top K”問題,如:在搜尋引擎中,統計搜尋最熱門的10個查詢詞;在歌曲庫中統計下載率最高的前10首歌等等。 2. 當

一個英文字串每個單詞出現的頻率

import java.util.*; public class Lookup{ public static void main(String[] args){ String s = "the instruction set of the Java virtual machine

100萬個數大的前100個數

1.演算法如下:根據快速排序劃分的思想 (1) 遞迴對所有資料分成[a,b)b(b,d]兩個區間,(b,d]區間內的數都是大於[a,b)區間內的數 (2) 對(b,d]重複(1)操作,直到最右邊的區間個數小於100個。注意[a,b)區間不用劃分 (3) 返回上

海量資料前k大數

前兩天面試3面學長問我的這個問題(想說TEG的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了),這個問題還是建立最小堆比較好一些。         先拿10000個數建堆,然後一次新增剩餘元素,如果大於堆頂的數(10000中最小的

海量日誌資料__怎麼在海量資料重複次數多的一個

 問題一: 怎麼在海量資料中找出重複次數最多的一個 演算法思想: 方案1:先做hash,然後求模對映為小檔案,求出每個小檔案中重複次數最多的一個,並記錄重複次數。         然後找出上一步求出的資料中重複次數最多的一個就是所求(如下)。 問題二:    

10個數大的10000個數(top K問題)

        前兩天面試3面學長問我的這個問題(想說TEG的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了),這個問題還是建立最小堆比較好一些。         先拿10000個數建堆,然後一次新增剩餘元素,如果大於堆頂的數(1

如何一個父串子串的個數

題目要求:輸入一個父字串,和一個子字串,編寫程式碼要求能夠實現計算出父串中子串的個數,例如:輸入父字串“hello”,輸入子字串“ll”,輸出結果為1。程式碼如下:#include <stdio.h> #include <string.h> void

陣列乘積大的三個數

題目: 給定一個無序陣列,包含正數、負數和0,要求從中找出3個數的乘積,使得乘積最大,要求時間複雜度:O(n),空間複雜度:O(1)  輸入描述: 無序整數陣列A[n] 輸出描述: 滿足條件的最大乘積 輸入例子1: 3 4 1 2 輸出例子1: 24 思路: 由於空間複雜

10個數大的10000個數(top K問題)

前兩天面試3面學長問我的這個問題(想說TEG的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了),這個問題還是建立最小堆

海量資料前k大數(topk問題)

前兩天面試3面學長問我的這個問題(想說TEG的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了),這個問題還是建立最小堆比較好一些。 先拿10000個數建堆,然後一次新增剩餘元素,如果大於堆頂的數(10000中最小

【面試必備】如何在10前1000大的數?

作者:channingbreeze | 微信公眾號:網際網路偵察小史是一個應屆生,雖然學的是電子

100個數大的前K個數(海量TopK問題)

對於這個問題,可以有以下思考: 給了多少記憶體儲存這100億個資料? 先思考:堆排序效率是nlogn,再思考:可以將這些資料切成等份,再從每一份中找出最大前k個數據,但是效率不高。那如果利用堆的性質呢? 小堆堆頂元素最小,先將前k個數建成小堆,那麼堆頂元素

用天平(只能比較,不能稱重)一堆小球其中唯一一個較輕的,使用x次天平,

1.用天平(只能比較,不能稱重)從一堆小球中找出其中唯一一個較輕的,使用x次天平, 最多可以從y個小球中找出較輕的那個,求y與x的關係式。 ----------------------------------------------- All other balls a

如何10資料快速判斷是否存在某一個元素

# 前言 當 `Redis` 用作快取時,其目的就是為了減少資料庫訪問頻率,降低資料庫壓力,但是假如我們某些資料並不存在於 `Redis` 當中,那麼請求還是會直接到達資料庫,而一旦在同一時間大量快取失效或者一個不存在快取的請求被惡意攻擊訪問,這些都會導致資料庫壓力驟增,這又該如何防止呢? # 快取雪崩