给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入首先给出正整数NN(\le 10^5≤105),为通话记录条数。随后NN行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
思路分析:使用散列,,真是不容易。用map超时,C++11实现了基于哈希的unordered_map,效率也非常快,用排序我没试,估计也超时吧。下面是使用散列的,考试要出来这么一题估计要花点时间。
#include <cstdio> #include <cstdlib> #include <string.h> typedef struct node { char phone[15]; // 存放电话号码 int num; // 统计出现次数 struct node* next; // 一下个结点的指针 } Node; typedef struct { int TableSize; Node* Table; } HashTable; int nextPrime( int n ) { while( 1 ) { bool flag = true; for( int i = 2; i < n; i++ ) { if( n % i == 0 ) { flag = false; break; } } if( flag ) break; n++; } return n; } HashTable* createHashTable( int n ) { HashTable* H = ( HashTable* )malloc( sizeof( HashTable ) ); H->TableSize = nextPrime( n ); H->Table = ( Node* )malloc( ( H->TableSize ) * sizeof( Node ) ); for( int i = 0; i < H->TableSize; i++ ) { H->Table[i].phone[0] = '\0'; H->Table[i].num = 0; H->Table[i].next = NULL; } return H; } int Hash( HashTable* H, char key[] ) { int index = 0; for( int i = 6; i <= 10; i++ ) { index = index * 10 + key[i] - '0'; } return index; } Node* Find( HashTable* H, char key[] ) { int index = Hash( H, key ) % ( H->TableSize ); // 初始散列位置 //printf( "初始散列位置: %d\n", index ); Node* p; p = H->Table[index].next; while( p && strcmp( p->phone, key ) ) { p = p->next; } return p; } void Insert( HashTable* H, char key[] ) { Node* p = Find( H, key ); if( !p ) { //printf( "没找到\n" ); Node* newNode = ( Node* )malloc( sizeof( Node ) ); int index = Hash( H, key ) % ( H->TableSize ); newNode->next = H->Table[index].next; H->Table[index].next = newNode; strcpy( newNode->phone, key ); newNode->num = 1; } else { //printf( "找到 %s\n", p->phone ); p->num++; } } void ScanAndOutput( HashTable* H ) { int i, MaxCnt, PCnt; char MinPhone[15]; MaxCnt = PCnt = 0; MinPhone[0] = '\0'; for( i = 0; i < H->TableSize; i++ ) { Node* ptr = H->Table[i].next; while( ptr ) { if( ptr->num > MaxCnt ) { MaxCnt = ptr->num; strcpy( MinPhone, ptr->phone ); PCnt = 1; } else if( ptr->num == MaxCnt ) { PCnt++; if( strcmp( MinPhone, ptr->phone ) > 0 ) { strcpy( MinPhone, ptr->phone ); } } ptr = ptr->next; } } printf( "%s %d", MinPhone, MaxCnt ); if( PCnt > 1 ) printf( " %d", PCnt ); printf( "\n" ); } void DestroyTable( HashTable* H ) { for( int i = 0; i < H->TableSize; i++ ) { Node* ptr = H->Table[i].next; while( ptr ) { Node* tmp = ptr->next; free( ptr ); ptr = tmp; } } free( H->Table ); free( H ); } int main() { //freopen( "123.txt", "r", stdin ); int N, i; char input[15]; scanf( "%d", &N ); // 创建Hash表 HashTable* H = createHashTable( 2 * N ); //printf( "%d\n", H->TableSize ); for( int i = 0; i < N; i++ ) { scanf( "%s", input ); Insert( H, input ); scanf( "%s", input ); Insert( H, input ); } ScanAndOutput( H ); DestroyTable( H ); return 0; }
