雜湊演算法 C語言 (陣列實現)
阿新 • • 發佈:2019-01-23
7-17 電話聊天狂人(25 分)
給定大量手機使用者通話記錄,找出其中通話次數最多的聊天狂人。
輸入格式:
輸入首先給出正整數N(≤105),為通話記錄條數。隨後N行,每行給出一條通話記錄。簡單起見,這裡只列出撥出方和接收方的11位數字構成的手機號碼,其中以空格分隔。
輸出格式:
在一行中給出聊天狂人的手機號碼及其通話次數,其間以空格分隔。如果這樣的人不唯一,則輸出狂人中最小的號碼及其通話次數,並且附加給出並列狂人的人數。
輸入樣例:
4 13005711862 13588625832 13505711862 13088625832 13588625832 18087925832 15005713862 13588625832
輸出樣例:
13588625832 3
這次來陣列實現,大體思路還是處理資料 然後插入。雜湊 用來大資料處理真的不錯。
/**根據同學的提醒 發現一個小BUG 在插入函式的 平方查詢合適位置的那個地方,現在已修改**/
程式碼:
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <ctype.h> #define MAX 400000 /** 定義 最大 陣列 大小 **///(感覺沒啥用 但是最好儘可能開大點,但是不要太大,不要超出系統可建造範圍) typedef struct Node *Hash; /**新的路程又開始了 這次準備用陣列來做雜湊 還有雙向平方處理衝突**/ struct Node{ char phone[15]; int num; }; int max(int x,int y) { if(x>y) return x; else return y; } char* minstr(char *x,char *y) { if(strcmp(x,y)>0) return y; else return x; } int nextprime(const int n) { int p =(n%2==1)? n+2:n+1; /**先找一個大於N的奇數**/ int i; while(p<MAX) { for(i=(int)sqrt(p);i>=2;i--) /**然後再判斷是不是素數**/ if(p%i==0) break; if(i<2) return p; /**是 那就返回這個數**/ else p+=2;/**不是 那就下一個奇數**/ } } int deal(char *s,int p) /**然後把字串對映成下標 (對映的方式很多很多,隨便猜一個靠譜的就行了)**/ { int index = (atoi(s+2))%p; return index; } int insert(Hash h,int pos,char *s,int p,int Max) /**雜湊查詢的插入實現 ,分別是雜湊陣列,陣列位置,身份證號,陣列最大大小, MAX 看到程式碼最後就明白了**/ { int i,posb=pos; /**備份pos值方便雙向平方查詢**/ for(i=1;;i++) { if(strcmp(h[pos].phone,"")==0) /**如果為pos的值空直接插入**/ { strcpy(h[pos].phone,s); h[pos].num++; Max=max(Max,h[pos].num); break; } else { if(strcmp(h[pos].phone,s)==0) /**不為空的話,就看看身份證號是不是想等**/ { h[pos].num++; Max=max(Max,h[pos].num); break; } else { //原p%2==1 if(i%2==1) pos=(posb+(i*i))%p; /**不相等 就找下一個位置 ,分別向後找一次和往前找一次,如此迴圈**/ else { //原i*i pos = posb-((i-1)*(i-1)); while(pos<0) pos+=p; } } } } return Max; } void initial(Hash h, int p) /**把雜湊陣列初始化 (初始化的動詞英文忘記咋寫了。。。。)**/ { int i; for(i=0;i<p;i++) { h[i].phone[0]='\0'; h[i].num=0; } } int main(){ int Max=0; int n; /**總數 N 然後就開始找 大於N的最小素數了**/ scanf("%d",&n); /**輸出中把\n也輸入進去 避免下面輸入會出現奇葩的事情**/ int p = nextprime(2*n); /**突然想起來 每次輸入的都是倆電話號碼,所以 電話號碼最大數是2*n**/ Hash h =(Hash)malloc(p*sizeof(struct Node));/**建立雜湊陣列**/ initial(h,p); char phone[15]; char phone1[15]; while(n--) { /*for(int i=0;i<p;i++) { printf("->>>%s %d\n",h[i].phone,h[i].num); } printf("the max is %d\n",Max);*/ scanf("%s %s",phone,phone1); Max=insert(h,deal(phone,p),phone,p,Max); Max=insert(h,deal(phone1,p),phone1,p,Max); } /*for(int i=0;i<p;i++) { printf("->>>%s %d\n",h[i].phone,h[i].num); } printf("the max is %d\n",Max);*/ int i,num=0; char *Minstr=NULL; for(i=0;i<p;i++) { if(h[i].num==Max) { if(Minstr==NULL) Minstr=h[i].phone; else Minstr=minstr(Minstr,h[i].phone); num++; } } printf("%s %d",Minstr,Max); if(num>1) printf(" %d",num); return 0; }