PTA_数据结构与算法题目集(中文)_7-14 电话聊天狂人 (25 分)_HASH_四种解法(学习C++_map & _unorder_map)

  • 题目地址
  • 题目解析:分析见中国MOOC数据结构,我这里将依次给出1、排序后统计解法,2、不完整的Hash解法(没有查找功能),3、C++中的map解答(最后一个测试点超时)4、C++中的unorder_map解答
  • 我的代码:

1、排序后统计

#include<stdio.h>
#include<stdlib.h>

int cmp(const void * a, const void * b)//注意使用的>,排序从小至大
{
	return *(long long int *)a > *(long long int *)b;
}

int main()
{
	int n, bb[200000];
	static long long int aa[200000];//也可使用char处理
	scanf("%d", &n); n *= 2;//成对输入
	for (int i = 0; i < n; i++)
	{
		scanf("%lld", &aa[i]);
		bb[i] = 1;//每个且不论重复的号码,均记录1次存在
	}
	qsort(aa, n, sizeof(long long int), cmp);

	int max = 1;
	for (int i = 1; i < n; i++)//后者若与前者相同,则后者=前者+1
		if (aa[i] == aa[i - 1])
		{
			bb[i] = bb[i - 1] + 1;
			if (bb[i] > max)
				max = bb[i];
		}

	int cnt = 0;
	for (int i = 0, flag = 1; i < n; i++)
		if (bb[i]==max)
		{
			cnt++;
			if (flag)//输出max中最小号码
			{
				printf("%lld ", aa[i]);
				flag--;
			}
				
		}
	printf("%d", max);
	if (cnt>1)
		printf(" %d", cnt);

	return 0;
}

2、不完整Hash(没有查找功能)

#include<stdio.h>
#include<string.h>

char aa[500000][12] = { '\0' };
int n, bb[500000] = { 0 }, max = 0;
void insertHash(char * val, int key);

//这里的计算法利用11位电话后6位,若6位的首位大于4则-5,用作键名
//由于6位的首位被改变,则利用前6位(第6个即可能被-5那位),来保证存储值唯一
//由于装填因子最大为0.4,故采用线性探测法解决冲突
int main()
{
	scanf("%d", &n);
	char ss[12] = { '\0' };
	for (int i = 0, key, ki = 1; i < n * 2; i++, ki = 1)
	{
		scanf("%s", ss);
		//键名计算
		key = (ss[5] - '0') > 4 ? ss[5] - '0' - 5 : ss[5] - '0';
		while (ki < 6)
			key = key * 10 + ss[5 + ki++] - '0';
		insertHash(ss, key);
	}
	int cnt = 0;
	for (int i = 0; i < 500000; i++)
		if (bb[i] == max)
		{
			cnt++;
			if (cnt == 1)
				strcpy(ss, aa[i]);
			else if (strcmp(ss, aa[i]) > 0)
				strcpy(ss, aa[i]);
		}
	printf("%s %d", ss, max);
	if (cnt > 1)
		printf(" %d", cnt);

	return 0;
}
void insertHash(char * val, int key)
{
	while (aa[key][0] != '\0' && strcmp(aa[key], val))
	{
		if (key + 1 < 500000)
			key++;
		else
			key = 0;
	}
	if (aa[key][0] == '\0')
		strcpy(aa[key], val);
	bb[key]++;

	if (bb[key] > max)
		max = bb[key];

	return;
}

3、C++_map(最后一个测试点超时)

#include<iostream>
#include<map>
#include<string>
using namespace std;

int main()
{
	int n, max = 0, cnt = 0;
	map<string, int>m;
	scanf("%d", &n); n *= 2;

	string ss;
	for (int i = 0; i < n; i++)
	{
		cin >> ss;//string只能使用cin cout处理
		if (!m.count(ss))//利用count查看是否存在
			m[ss] = 0;
		m[ss]++;
		if (m[ss]>max)
			max = m[ss];
	}
	for (auto it = m.begin(); it != m.end(); it++)
		if (it->second==max)
		{
			cnt++;
			if (cnt==1)
				ss = it->first;//c++_string真方便
		}
	cout << ss;
	printf(" %d", max);
	if (cnt>1)
		printf(" %d", cnt);

	return 0;
}

4、C++_unorder_map

#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;

int main()
{
	int n, max = 0, cnt = 0;
	unordered_map<string, int>m;
	scanf("%d", &n); n *= 2;

	string ss;
	for (int i = 0; i < n; i++)
	{
		cin >> ss;
		if (!m.count(ss))
			m[ss] = 0;
		m[ss]++;
		if (m[ss]>max)
			max = m[ss];
	}
	for (auto it = m.begin(); it != m.end(); it++)
		if (it->second==max)
		{
			cnt++;
			if (cnt==1)
				ss = it->first;
			if (ss> it->first)//因为为无向图,故需找到max的最小号码,string真香
				ss = it->first;
		}
	cout << ss;
	printf(" %d", max);
	if (cnt>1)
		printf(" %d", cnt);

	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值