给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。

输入格式:

输入首先给出正整数NN(\le 10^5≤10​5​​),为通话记录条数。随后NN行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。

输出格式:

在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。

输入样例:

4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832

输出样例:

13588625832 3
/*
* 就这道题而言:如果采取直接电话号码长度为11 直接排序O(11 * n * log n ) 然后在找出现最多的O(11 * n) 时间效率比采用散列表还要好点- -
1.上述方案在实际应用中不可行 应为会涉及到不断插入新号码的问题 每插入一个新号码都要重新进行排序。
可以考虑用散列表解决 这题哈希函数采用除留余数法 解决冲突采用分离链接法。
*/
#include "iostream"
#include "cmath"
#include "cstring"
using namespace std;
#define KEYLENGTH 11
typedef char ElementType[KEYLENGTH];
typedef int Index; /* 散列地址类型 */ struct LNode {
ElementType data;
LNode* next;
int count;
};
typedef LNode *ptrToLNode;
typedef ptrToLNode Position;
typedef ptrToLNode List;
typedef struct TblNode* HashTable;
struct TblNode { /* 散列表节点定义 */
int tableSize; /* 表的大小 */
List heads; /* 指向链表头结点的数组 */
};
#define MAXTABLESIZE 1000000
int nextPrime(int n) {
int i, p = (n % ) ? n + : n + ;
while (p < MAXTABLESIZE) {
for (i = sqrt(p); i > ; i--)
if (!(p%i))
break;
if (i == )
break;
else
p += ;
}
return p;
}
HashTable createTable(int tableSize) {
HashTable h;
int i;
h = (HashTable)malloc(sizeof(struct TblNode));
h->tableSize = nextPrime(tableSize);
h->heads = (List)malloc(h->tableSize* sizeof(struct LNode));
for (i = ; i < h->tableSize; i++) {
h->heads[i].data[] = '\0'; h->heads[i].next = NULL;
h->heads[i].count = ;
}
return h;
} int Hash(int p, int tableSize) { /* 设置映射的哈希函数 */
return p % tableSize; /* 采用除留余数法 */
} Position find(HashTable h , ElementType key) {
Position p;
Index pos;
pos = Hash(atoi(key+KEYLENGTH-),h->tableSize); /* 初始散列位置 */
p = h->heads[pos].next; /* 从该链表的第一个节点开始 */
while (p && strcmp(p->data, key)) /* 未到表尾 并且key未找到时 */
p = p->next;
return p;
} bool insert(HashTable h, ElementType key) {
Position p, newCell;
Index pos;
p = find(h, key);
if (!p) {
newCell = (Position)malloc(sizeof(struct LNode));
strcpy(newCell->data, key);
newCell->count = ;
pos = Hash(atoi(key + KEYLENGTH - ), h->tableSize); /* 初始散列位置 */
/* 头插法 将newCell作为h->heads[pos]的第一个结点 */
newCell->next = h->heads[pos].next;
h->heads[pos].next = newCell;
return true;
}
else {
p->count++;
return false;
}
} void scanAndOutput(HashTable h) {
int i, MaxCnt, PCnt;
MaxCnt = PCnt = ;
ElementType MinPhone;
List ptr;
MinPhone[] = '\0';
for (i = ; i < h->tableSize; i++) {
ptr = h->heads[i].next;
while (ptr) {
if (ptr->count > MaxCnt) {
MaxCnt = ptr->count;
strcpy(MinPhone, ptr->data);
PCnt = ;
}
else if (ptr->count == MaxCnt) {
PCnt++;
if (strcmp(MinPhone, ptr->data) > )
strcpy(MinPhone, ptr->data);
}
ptr = ptr->next;
}
}
cout << MinPhone << " "<< MaxCnt ;
if (PCnt > )
cout << " "<<PCnt;
cout << endl;
} void destroyTable(HashTable h) {
int i;
Position p, temp;
for (i = ; i < h->tableSize; i++) {
p = h->heads[i].next;
while (p != NULL) {
temp = p->next;
free(p);
p = temp;
}
}
free(h->heads);
free(h);
}
int main() {
int n, i;
ElementType key;
cin >> n;
HashTable h = createTable( * n);
for (i = ; i < n; i++) {
cin >> key; insert(h, key);
cin >> key; insert(h, key);
}
scanAndOutput(h);
destroyTable(h);
return ;
}
04-26 09:54