C++数据结构——小明的通讯录(哈希表线性探测法)

小明的通讯录

小明上中学了,为了方便和家里以及同学联系,爸爸终于给小明买了一台手机。该手机的存储容量可以扩充,因此,可以存储的电话号码数量没有限制。
小明的手机有一个特殊的功能,对于打进或拨出的电话,只要是新号码,手机均会自动进行储存。
给定小明在一个月的使用期间的手机通讯记录,请给出此时此刻小明的手机中存储了多少个电话号码。

输入格式:

本题只有一组测试数据。第一行先输入一个整数N( N不超过1000000),第二行输入N个电话号码。
为方便计算机处理,假设电话号码的长度是7位数,也就是范围在1000000到9999999之间。

输出格式:

输出小明的手机中存储的电话号码总数。

输入样例:
7
1000002 3000004 9000002 1000002 1000011 1234567 1000002
输出样例:
5
提示:

为提高输入效率,建议使用scanf()函数。 或者使用以下语句提高cin、cout的效率: ios::sync_with_stdio(false);

解题代码

#include
using namespace std;
int findPrime(int n)//找到不大于n的最大素数,减少冲突 
{
	int flag;
	for(int i=n;i>=2;i--){
		flag=1;
		for(int j=2;j<=sqrt(i);j++){
			if(i%j==0){
				flag=0;
				break;
			}
		}
		if(flag) return i;
	}
	return 0;
}

int main()
{
	int n,m,num,p,cnt;
	while(cin>>n)
	{
		int hash_num[n]={0};
		m = findPrime(n);
		for(int i=0;i<n;i++){
			scanf("%d",&num);//用scanf,提高输入效率 
			p=num%m;
			while(hash_num[p]!=0&&hash_num[p]!=num){
				p=(p+1)%m;//线性探测法 
			}
			hash_num[p]=num;
		}
		cnt=0;
		for(int i=0;i<n;i++){
			if(hash_num[i]!=0){
				cnt++;
			}
		}
		cout<<cnt<<endl;
	}
}

解题思路
使用哈希表进行存储,并且使用线性探测法解决冲突问题。首先先找到一个不大于n的最大质数,找质数的原因是为了减少冲突,如果我们的m设置为4,那么2的倍数就会增加冲突次数.
然后得到我们的下标p=num%m通过while循环判断当前这个位置是否为空或者找的这个位置是不是等于输入的num,如果符合条件while循环结束,不符合则接着找,然后在该位置插入num就可以了,最后循环找到不为0的位置,求数量输出就行了。

解题代码

#include
using namespace std;
int main()
{
    int n,num;
    
    while(cin>>n){
        map<int,int> list;
        for(int i=0;i<n;i++){
            scanf("%d",&num);
            list[num]=1;
        }
        cout<<list.size()<<endl;
    }
}

解题思路
这个代码很简洁,我偷懒这么写的,就是使用STL的map容器,map是红黑树,其实也可以用set做,set也是红黑树,是一种自平衡的二叉搜索树,键值唯一,所以做起来还是很方便的。

你可能感兴趣的:(C/C++算法数据结构,c++,数据结构,开发语言)