PAT 电话聊天狂人

看到一个人的解题思路,学到了他的算时间的一种方法,特记录一下

11-散列1 电话聊天狂人   (25分)

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

输入格式:

输入首先给出正整数N105),为通话记录条数。随后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;  
}  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值