基础实验5-2.2 电话聊天狂人 (25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<math.h>
#include<string.h>
#define KEYLENGTH 11
#define MaxTblSize 1000000
typedef char ElementType[KEYLENGTH+1];
typedef struct LNode* PtrToNode;
struct LNode {
ElementType Data;
int Times;
PtrToNode Next;
};
typedef PtrToNode List;
typedef PtrToNode Position;
typedef struct TblNode* HashTable;
int Hash(int Key, int Prim);
struct TblNode {
int TblSize;
List Head;
};
HashTable CreateTable(int TableSize);
int NextPrime(int N);
void DestoryTable(HashTable H);
int FindMinPrime(int N);
void Insert(HashTable H, ElementType Item, int Prim);
Position Find(HashTable H, ElementType Item, int Prim, int* a);
Position FindCrazy(HashTable H, int* a);
int main()
{
int N;
ElementType Key;
scanf("%d", &N);
HashTable Table = CreateTable(2 * N);
int Prim = FindMinPrime(Table->TblSize);
for (int i = 0; i < N; i++)
{
scanf("%s", Key);
Insert(Table, Key, Prim);
scanf("%s", Key);
Insert(Table, Key, Prim);
}
Position Ptr = FindCrazy(Table, &N);
if (N == 1)
{
printf("%s %d", Ptr->Data, Ptr->Times);
}
else
{
printf("%s %d %d", Ptr->Data, Ptr->Times, N);
}
}
HashTable CreateTable(int TableSize)
{
HashTable Table = (HashTable)malloc(sizeof(struct TblNode));
Table->TblSize = NextPrime(TableSize);
Table->Head = (List)malloc(sizeof(struct LNode) * (Table->TblSize));
for (int i = 0; i < Table->TblSize; i++)
{
Table->Head[i].Next = NULL;
Table->Head[i].Data[0] = '\0';
Table->Head[i].Times = 0;
}
return Table;
}
int Hash(int Key, int Prim)
{
return Key % Prim;
}
Position Find(HashTable H, ElementType Item,int Prim,int*a)
{
int Num = atoi(Item + 6);
int P = Hash(Num, Prim);
*a = P;
Position Ptr=H->Head[P].Next;
while (Ptr && strcmp(Ptr->Data, Item))
Ptr = Ptr->Next;
return Ptr;
}
int NextPrime(int N)
{
int i;
if (N % 2 == 0)
N = N + 1;
else
N = N + 2;
while (N <= MaxTblSize)
{
for (i = (int)sqrt(N); i > 2; i--)
{
if (N % i == 0)
break;
}
if (i == 2)
return N;
else
N = N + 2;
}
}
void Insert(HashTable H, ElementType Item,int Prim)
{
int a;
Position Ptr = Find(H, Item,Prim,&a);
if (Ptr)
{
Ptr->Times++;
}
else
{
Ptr = (List)malloc(sizeof(struct LNode));
Ptr->Times = 1;
strcpy(Ptr->Data, Item);
Ptr->Next = H->Head[a].Next;
H->Head[a].Next = Ptr;
}
}
void DestoryTable(HashTable H)
{
Position Ptr;
Position Tmp;
for (int i = 0; i < H->TblSize; i++)
{
Ptr = H->Head[i].Next;
while (Ptr != NULL)
{
Tmp = Ptr;
Ptr = Ptr->Next;
free(Tmp);
}
}
free(H->Head);
free(H);
}
int FindMinPrime(int N)
{
int i;
if (N < 4)
return N;
else if (N == 4)
return 3;
else
{
int P = (N % 2) ? N : N-1;
while (1)
{
for (i = (int)sqrt(P); i > 2; i--)
{
if (P % i == 0)
{
break;
}
}
if (i == 2)
return P;
else
P = P - 2;
}
}
}
Position FindCrazy(HashTable H,int*a)
{
Position Ptr=(Position)malloc(sizeof(struct LNode));
Position Tmp;
Ptr->Times = 0;
for (int i = 0; i < H->TblSize; i++)
{
Tmp = H->Head[i].Next;
while (Tmp != NULL)
{
if (Tmp->Times > Ptr->Times)
{
Ptr = Tmp;
*a = 1;
}
else if (Tmp->Times == Ptr->Times)
{
if (strcmp(Tmp->Data, Ptr->Data)<0)
{
Ptr = Tmp;
}
*a = *a + 1;
}
Tmp = Tmp->Next;
}
}
return Ptr;
}
卡了一个小时!!!!!!!!就因为字符串不可以直接比较大小!!!!!!!!!!!!!!!!!!!!看来必须了解一个东西才能进行使用,否则都不知道是怎么错的!!