POJ 2945 Find the Clones

本文讨论了如何使用Map数据结构解决给定问题,即确定字符串在一系列输入中出现的频率。通过实例演示了从输入读取数据、使用Map进行计数以及输出结果的过程。重点介绍了自定义比较函数和字符串数组的使用,以优化内存和提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

Doubleville, a small town in Texas, was attacked by the aliens. They have abducted some of the residents and taken them to the a spaceship orbiting around earth. After some (quite unpleasant) human experiments, the aliens cloned the victims, and released multiple copies of them back in Doubleville. So now it might happen that there are 6 identical person named Hugh F. Bumblebee: the original person and its 5 copies. The Federal Bureau of Unauthorized Cloning (FBUC) charged you with the task of determining how many copies were made from each person. To help you in your task, FBUC have collected a DNA sample from each person. All copies of the same person have the same DNA sequence, and different people have different sequences (we know that there are no identical twins in the town, this is not an issue).

根据以上描述信息可以将本题抽象为:给出一给字符串,数量为n,每个字符串的长度为m,输出出现i(1<=i<=n)次的字符串的个数。

解题思路:

最近在学习字典树,刚开始看到这题也想用字典树来做。思考后发现其实可以用更简单的map来实现。定义类型为map<char*, int>的变量,记录字符串出现的次数。然后开辟数组num[20000],记录出现i(1<=i<=n)次的字符串的个数。再遍历map,以当前字符串出现的字数减1记为k作为索引,更新num[k],使得num[k]++。

实现时需要注意的地方:

1、因为在定义map时的key类型是char *,因此需要自定义比较函数。

2、为避免每次都new新的字符串,定义字符数组,需要new的地方,直接从数组中取。


Memory: 1184K Time: 2938MS

#include <cstdio>
#include <map>
#include <cstring>
using namespace std;

struct cmp //自定义比较函数
{
	bool operator()(const char *s1, const char *s2) const
	{
		return strcmp(s1, s2) < 0;
	}
};

int main()
{
	char *dna;
	char dnas[20000][21]; //字符数组,需要new的地方直接取
	int num[20000];
	map<char*, int, cmp> mp;
	int i, j, m, n;
	
	while(scanf("%d%d", &n, &m))
	{
		if(n == 0 && m == 0)
			break;

		j = 0;
		mp.clear();
		for(i = 0; i < n; i++)
		{
			dna = dnas[j++]; //从数组中直接取
			scanf("%s", dna);
			mp[dna]++;
		}

		memset(num, 0, sizeof(num));
		map<char*, int, cmp>::iterator iter = mp.begin();
		while(iter != mp.end())
		{
			num[iter->second - 1]++;
			iter++;
		}
		for(i = 0; i < n; i++)
		{
			printf("%d\n", num[i]);
		}
	}

	return 0;
}
利用map实现,程序的执行效率比较低。有时间再用Trie方法实现,比较两者的效率(猜测Trie肯定比map实现高效)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值