您的位置:首页 > 其它

PAT 电话聊天狂人

2017-07-13 09:34 337 查看
看到一个人的解题思路,学到了他的算时间的一种方法,特记录一下11-散列1 电话聊天狂人   (25分)给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。

输入格式:

输入首先给出正整数N(≤10​5​​),为通话记录条数。随后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->cou4000nt=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 5typedef 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;}  
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  散列