1. 程式人生 > >模擬實現atoi和itoa以及100G 的IP地址求出現次數最多的前K個IP

模擬實現atoi和itoa以及100G 的IP地址求出現次數最多的前K個IP

1.模擬實現C庫的atoi和itoa。

2.給一個超過100G的log file, log中存著IP地址, 設計演算法找到出現次數最多的100個IP地址?

1.題考察面試者的思維方式:完整性和魯棒性
先想好測試用例,溝通好錯誤處理,才能滿意的做完。

錯誤需要考慮的情況有:
1.當字串為空時返回0,0字串返回值也是0,但是兩者的含義不同,我們應該做到區分,怎麼區分? 定義全域性變數,設定有效無效
2.“+123”“-565”,
3.數值溢位
4.字串為NULL
5.穿入非法字元,怎麼解決?
6.“+”“-” (+ - 號後面沒有跟數字)

enum Status{kValid=0
,kInvalid}; int g_nstatus = kValid; long long strToIntCore(const char* digit,bool minus) { long long num = 0; while (*digit) { if (*digit >= '0'&*digit <= '9') { int flag = minus ? -1 : 1; num = num * 10 + flag*(*digit - '0'); if
(!minus&&num > 0x7FFFFFFF || minus&&num < 0x80000000) { num = 0; break; } } else { break; } digit++; } if (*digit == '\0') { g_nstatus = kValid; } return
num; } int myatoi(const char* str) { g_nstatus = kInvalid; //(初始化為無效值) long long num = 0; if (str == NULL || *str != '\0') { bool minus=false; if (*str == '+') { str++; minus = false; } if (*str == '-') { str++; minus = true; } if (!*str != '\0') { num = strToIntCore(str,minus); } } return (int)num; } ///////////////////////////////////////////////// char* myitoa(int num,char* str,int radix) { char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; unsigned int unum = 0; int i = 0; if (radix == 10 && *str == '-') { str[i++] = '-'; } unum = (unsigned)num; do { str[i++] = index[unum % radix]; unum = unum / radix; } while (unum); str[i] = '\0';//字串\0結尾 int k = 0; //字串翻轉 if (str[0] == '-') { k = 1; } i = i - 1; for (k; k <=i;)//基數個元素會相聚到一個元素上, 偶數個元素會錯開位置 { char temp = str[i]; str[i] = str[k]; str[k] = temp; k++; i--; } return str; }

2.給一個超過100G的log file, log中存著IP地址, 設計演算法找到出現次數最多的100個IP地址?

一般來講求topK 問題,建堆求topK來解決大資料問題非常有效。
此處來進行求解出現次數最多的IP地址,

首先看到100G的日誌檔案,我們的第一反應肯定是太大了,根本載入不到記憶體,更別說設計演算法了,那麼怎麼辦呢?既然裝不下,我們是不是可以將其切分開來,一小部分一小部分輪流進入記憶體呢,答案當然是肯定的。

在這裡要記住一點:但凡是大資料的問題,都可通過切分來解決它。

粗略算一下:如果我們將其分成1000個小檔案,每個檔案大概就是500M左右的樣子,現在計算機肯定輕輕 鬆鬆就能裝下。

那麼,問題又來了,怎樣才能保證相同的IP被分到同一個檔案中呢?

這裡我想到的是雜湊切分,使用相同的雜湊函式(如 BKDRHash)將所有IP地址轉換為一個整數key,再利用 index=key%1000就可將相同IP分到同一個檔案。

依次將這1000個檔案讀入記憶體,出現次數最多的IP進行統計。

最後,在1000個出現次數最多的IP中找出最大的出現次數即為所求。

用到的雜湊函式:

與上題條件相同,如何找到TOP K的IP?

答:

這倒題說白了就是找前K個出現次數最多的IP,即降序排列IP出現的次數。

與上題類似,我們用雜湊切分對分割的第一個個小檔案中出現最多的前K個IP建小堆,

然後讀入第二個檔案,將其出現次數最多的前K個IP與 堆中資料進行對比,

如果包含大於堆中的IP出現次數,則更新小堆,替換原堆中次數的出現少的資料

再讀入第三個檔案,以此類推……

直到1000個檔案全部讀完,堆中出現的K個IP即是出現 次數最多的前K個IP地址。

相關推薦

模擬實現atoiitoa以及100GIP地址出現次數KIP

1.模擬實現C庫的atoi和itoa。 2.給一個超過100G的log file, log中存著IP地址, 設計演算法找到出現次數最多的100個IP地址? 1.題考察面試者的思維方式:完整性和魯棒性 先想好測試用例,溝通好錯誤處理,才能滿意

Linux awk統計日誌中出現過的IP(或出現次數的NIP)

awk是一個強大的文字分析工具,相對於grep的查詢,sed的編輯,awk在其對資料分析並生成報告時,顯得尤為強大。簡單來說awk就是把檔案逐行的讀入,以空格為預設分隔符將每行切片,切開的部分再進行各種分析處理。 awk的用法 awk 'BEGIN{ commands }

從一億ip找出出現次數IP(分治法)

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

1、(topK問題)海量日誌資料,提取出某日訪問百度次數的10IP

#include <iostream>#include <fstream>#include <string.h>#include <ctime>#include <hash_map>#include <sys/socket.h>#incl

使用python找出nginx訪問日誌中訪問次數的10ip排序生成網頁

#encoding=utf-8 # 找到日誌中的top 10,日誌格式如下 #txt = '''100.116.167.9 - - [22/Oct/2017:03:55:53 +0800] "HEAD /check HTTP/1.0" 200 0 "-" "-" "-" ut = 0.001''' #n

PTA-n以內大的k素數以及它們的(C語言)

輸入樣例1: 1000 10 輸出樣例1: 997+991+983+977+971+967+953+947+941+937=9664 輸入樣例2: 12 6 輸出樣例2: 11+7+5+3+2=28 #include <stdio.h> //判斷素數 int prime(i

7-51 n以內大的k素數以及它們的 (20 分)

7-51 求n以內最大的k個素數以及它們的和 (20 分) 本題要求計算並輸出不超過n的最大的k個素數以及它們的和。 輸入格式: 輸入在一行中給出n(10≤n≤10000)和k(1≤k≤10)的值。 輸出格式: 在一行中按下列格式輸出: 素數1+素數2+…+素數k

PTA教輔 n以內大的k素數以及它們的

5-22 求n以內最大的k個素數以及它們的和   (20分) 本題要求計算並輸出不超過n的最大的k個素數以及它們的和。 輸入格式: 輸入在一行中給出n(10≤\le≤n≤\le≤10000)和k(

n以內大的k素數以及它們的

import java.util.Scanner; public class sushu {     public static void main(String[] args) {         Scanner scanf =new Scanner(System.

PTA 7-14 n以內大的k素數以及它們的(20 分)

本題要求計算並輸出不超過n的最大的k個素數以及它們的和。 輸入格式: 輸入在一行中給出n(10≤n≤10000)和k(1≤k≤10)的值。 輸出格式: 在一行中按下列格式輸出: 素數1+素數2+…+素數k=總和值 其中素數按遞減順序輸出。若n以內不夠k個素數,則按實際個數輸出。 輸入樣例1: 1000

7-51 n以內大的k素數以及它們的(20 分)

題目: 本題要求計算並輸出不超過n的最大的k個素數以及它們的和。 輸入格式: 輸入在一行中給出n(10≤n≤10000)和k(1≤k≤10)的值。 輸出格式: 在一行中按下列格式輸出: 素數1+素數2+…+素數k=總和值 其中素數按遞減順序輸出

7-51 n以內大的k素數以及它們的

7-51 求n以內最大的k個素數以及它們的和(20 分) 本題要求計算並輸出不超過n的最大的k個素數以及它們的和。 輸入格式: 輸入在一行中給出n(10≤n≤10000)和k(1≤k≤10)

中M2018春C入門進階練習集-程式設計題51 7-51 n以內大的k素數以及它們的(20 分)

7-51 求n以內最大的k個素數以及它們的和(20 分) 本題要求計算並輸出不超過n的最大的k個素數以及它們的和。 輸入格式: 輸入在一行中給出n(10≤n≤10000)和k(1≤k≤10)的值。 輸出格式: 在一行中按下列格式輸出: 素數1+素數2+…+素數k=

40.@返回字符串中出現次數的那個字符次數2

script 最大 spl 技術分享 char 獲取 code java log 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="U

判斷一個字符串之中出現次數的字符出現次數

div char for ole ++ 思路 i++ 最大值 sdh 判斷一個字符串之中出現次數最多的字符和它出現的次數!!! 思路:用一個空對象將字符串的各個字符和其出現的次數緩存起來,再通過比較次數的大小來判斷出最大值 (function(){ // 判斷一個

面試題:字串出現次數的字母次數(基礎思路篇)

今天中午公司要求的小功能寫完之後,想了想之前的一道面試題。 題目: 給一個字串,找到出現次數最多的字母和次數(手寫程式碼) 當時想到了用map,但是寫了一半感覺到自己對map還是不熟練,手寫寫不出來,於是就換了個思路。 原理: 通過字串分割函式分割字串,判斷分割後的長度來比較字母的次

java中輸出一個字串中出現次數的字元以及次數

1 先把字串轉化為陣列 .toCharArray 2 定義一個數組count[i] 存取每個字元 以及數量 count[i]++ 3 計算每個字元 以及值 4 取count的最大值 public class MaxString { public sta

js陣列中出現次數第二的元素

整型陣列中出現次數最多和第二多的元素 用雜湊陣列 function f(arr){ var i; var length=arr.length; var hash=[]

508. 出現次數的子樹元素

給出二叉樹的根,找出出現次數最多的子樹元素和。一個結點的子樹元素和定義為以該結點為根的二叉樹上所有結點的元素之和(包括結點本身)。然後求出出現次數最多的子樹元素和。如果有多個元素出現的次數相同,返回所有出現次數最多的元素(不限順序)。 示例 1 輸入: 5 / \ 2 -3

上千萬或上億資料(有重複),統計其中出現次數的N個數據. C++實現

上千萬或上億的資料,現在的機器的記憶體應該能存下。所以考慮採用hash_map/搜尋二叉樹/紅黑樹等來進行統計次數。然後就是取出前N個出現次數最多的資料了,可以用第2題提到的堆機制完成。 #in