看到一个人的解题思路,学到了他的算时间的一种方法,特记录一下
11-散列1 电话聊天狂人 (25分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
以下是它计算时间的一种方法,学习一下!!!!!!!!!!!!!!!
int main()
{
HashTable H;
int N, maxSame = 1;
ElementType send, rec;
start = clock();
cin >> N;
H = InitializeTable(2*N);
for (int i = 0; i != N; ++i) {
cin >> send >> rec;
Insert(send, H);
Insert(rec, H);
}
stop = clock();
duration = ((double)(stop - start)) / CLK_TCK;
cout << duration << endl;
start = clock();
FindMax(H);
stop = clock();
duration = ((double)(stop - start)) / CLK_TCK;
cout << duration << endl;
DestroyTable(H);
}
自己对着PAT教程写了一遍,但还没测试,先把代码贴上来有时间测试
#include "stdafx.h"
#include"stdlib.h"
#include"iostream"
#include"math.h"
#define MAXTABLESIZE 100000
//电话号码11位,还有个结束符
typedef char ElementType[12];
typedef struct ListNode *position;
typedef position List;
typedef struct HashTb *HashTable;
struct ListNode{
int count;
ElementType PhoneNum;
position next;
};
struct HashTb{
int MaxSize;
List head;
};
int Hash(int key,int p)
{
return key%p;
}
int NextPrime( int N )
{ /* 返回大于N且不超过MAXTABLESIZE的最小素数 */
int i, p = (N%2)? N+2 : N+1; /*从大于N的下一个奇数开始 */
while( p <= MAXTABLESIZE ) {
for( i=sqrt((long double)p); i>2; i-- )
if ( !(p%i) ) break; /* p不是素数 */
if ( i==2 ) break; /* for正常结束,说明p是素数 */
else p += 2; /* 否则试探下一个奇数 */
}
return p;
}
HashTable createtable(int size)
{
HashTable H;
H=(HashTable)malloc(sizeof(struct HashTb));
H->MaxSize=NextPrime(size);//找大于它的最小素数
H->head=(List)malloc(sizeof(struct ListNode)*(H->MaxSize));
for(int i=0;i<(H->MaxSize);i++)
{
H->head[i].count=0;//注意 这里是数组不用->形式调用
H->head[i].PhoneNum[0]='\0';
H->head[i].next=NULL;
}
return H;
}
position Find(HashTable H,ElementType Key)
{
position P;
int Pos;
Pos=Hash(atoi(Key+11-5),H->MaxSize);//因为后五位随机性较大所以算后5位
P=H->head[Pos].next;
while(P&&strcmp(Key,P->PhoneNum))//判断下一个结点是否为空及号码是否为要找的,strcmp相等返回0
{
P=P->next;
}
return P;//不管找没找到返回P
}
bool Insert(HashTable H,ElementType Key)
{
position P,NewCell;
int Pos;
P=Find(H,Key);
if(P!=NULL)
{
P->count++;
return false;
}
else//关键字未找到 可以插入
{
NewCell=(position)malloc(sizeof(struct ListNode));
/NewCell->PhoneNum=Key;这里直接对数组名赋值错误,数组必须用strcpy函数
strcpy(NewCell->PhoneNum,Key);
NewCell->count=1;
Pos=Hash(atoi(Key+11-5),H->MaxSize);
P=H->head[Pos].next;
NewCell->next=H->head[Pos].next;
H->head[Pos].next=NewCell;
return true;
}
}
void ScanAndOutput(HashTable H)
{
int i,MAXcnt=0;//记录狂人通话次数;
int Pcnt=0;//记录狂人个数;
ElementType MinPhone;//记录狂人最小手机号码
List Ptr;
MinPhone[0]='\0';
for(i=0;i<H->MaxSize;i++)//扫描链表
{
Ptr=H->head[i].next;
while(Ptr)
{
if(Ptr->count>MAXcnt){//更新最大通话次数
MAXcnt=Ptr->count;
strcpy(MinPhone,Ptr->PhoneNum);
Pcnt=1;
}
else if(Ptr->count==MAXcnt){
Pcnt++;//狂人计数
if(strcmp(MinPhone,Ptr->PhoneNum)>0)
strcpy(MinPhone,Ptr->PhoneNum);//跟新狂人的最小手机号码
}
Ptr=Ptr->next;
}
}
printf("%s %d",MinPhone,MAXcnt);
if(Pcnt>1)
printf("%d\n",Pcnt);
}
int main()
{
int i,N;
HashTable H;
ElementType KEY;
scanf("%d",&N);
H=createtable(N*2); //因为一行两个电话
for(i=0;i<N;i++)
{
scanf("%s",&KEY);
Insert(H,KEY);
scanf("%s",&KEY);
Insert(H,KEY);
}
ScanAndOutput(H);
system("pause");
return 0;
}
这里再列出个参考代码
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "string.h"
#define KEYLENGTH 11
#define MAXD 5
typedef char ElementType[KEYLENGTH+1];
typedef unsigned int Index;
typedef struct LNode* PtrToLNode;
struct LNode
{
ElementType Data;
PtrToLNode Next;
int Count; //计数器
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
typedef struct TblNode* HashTable;
struct TblNode
{
int TableSize;
List head;
};
int NextPrime(int N) //散列表的长度一般是比预计个数大的最小素质,这里就是求最小素数
{
int i;
if(N%2==0)
N++;
for(;;N+=2)
{
for(i=3;i*i<=N;i+=2)
if(N%i==0)
break;
if(i*i>N)
return N;
}
}
HashTable CreateTable(int HashSize)
{
HashTable H;
int i;
HashSize=NextPrime(HashSize);
H=(HashTable)malloc(sizeof(struct TblNode));
H->TableSize=HashSize;
H->head=(List)malloc(HashSize*sizeof(struct LNode));
for(i=0;i<HashSize;i++)
{
H->head[i].Data[0]='\0';
H->head[i].Next=NULL;
}
return H;
}
int Hash(int key,int p)
{
return key%p;
}
Position Find(HashTable H,ElementType KEY)
{
Index pos;
Position p;
pos=Hash(atoi(KEY+KEYLENGTH-MAXD),H->TableSize);
p=H->head[pos].Next;
while(p&&strcmp(KEY,p->Data))
{
p=p->Next;
}
return p;
}
void Insert(HashTable H,ElementType Key)
{
Position P,NewNode;
Index pos;
P=Find(H,Key);
if(!P)
{
NewNode=(Position)malloc(sizeof(struct LNode));
strcpy(NewNode->Data,Key);
NewNode->Count=1;
pos=Hash(atoi(Key+KEYLENGTH-MAXD),H->TableSize);
NewNode->Next=H->head[pos].Next;
H->head[pos].Next=NewNode;
}
else
{
P->Count++;
}
}
void ScanAndOutput(HashTable H)
{
int i,Maxcnt=0,Pcnt=0;
ElementType Minphone;
Position p;
Minphone[0]='\0';
for(i=0;i<H->TableSize;i++)
{
p=H->head[i].Next;
while(p!=NULL)
{
if(p->Count>Maxcnt)
{
Maxcnt=p->Count;
strcpy(Minphone,p->Data);
Pcnt=1;
}
else if(p->Count==Maxcnt)
{
if(strcmp(Minphone,p->Data)>0)
strcpy(Minphone,p->Data);
Pcnt++;
}
p=p->Next;
}
}
printf("%s %d",Minphone,Maxcnt);
if(Pcnt>1)
printf(" %d",Pcnt);
printf("\n");
}
int main()
{
int i,N;
HashTable H;
ElementType KEY;
scanf("%d",&N);
H=CreateTable(N);
for(i=0;i<2*N;i++)
{
scanf("%s",&KEY);
Insert(H,KEY);
}
ScanAndOutput(H);
return 0;
}