POJ1200——Crazy Search(散列表的应用)

本文介绍了解决POJ 1200问题的方法,使用散列表存储不同子串的散列值,以O(1)的时间复杂度进行查找和增加元素。文章详细解释了如何构建散列函数,确保每个子串都能得到唯一的结果。

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

题目来源http://poj.org/problem?id=1200
题目大意:随机给定一段内容,并且这段内容由NC中不同字符组成,求出长度为N的子串有多少种。边界条件为,子串的个数不超过16000000。
解题思路:利用散列表的思想,首先构建散列函数,将不同子串映射成唯一的散列值存放在散列表中,这样当执行查找元素和增元素时的时间复杂度均为O(1)。利用这一特性我们可以轻松完成该题目。
注意:该题目难点在于构建散列函数,利用进制的方式保证每个子串通过散列函数得到唯一的结果。
基于以上分析代码实现如下:

/*
* Copyright: (c) 2019
*
* 文件名称:  ACM1200.cpp	
* 文件标识:
* 摘	要:
*
* 版	本: 1.0
* 作	者: RF_LYF
* 创建日期:	 2019/5/15  13:33
*/
#include <stdio.h>
#include <string.h>
const int max_num = 16000000;
char str[max_num];
int num[256];
bool h[max_num];
int main()
{
int n ,nc;
while(~scanf("%d%d%s", &n, &nc, str))
{
	int nLen = strlen(str);
	int cnt = 1;
	for(int i = 0; cnt <= nc; ++i)
	{
		if(!num[str[i]])
			num[str[i]] = cnt++;
	}
	int sum = 0,pow=1;
	for(int i = 0; i < n; ++i)
	{
		if(i)
			pow *= nc;
		sum = sum * nc + num[str[i]];
	}
	int ans = 0;
	if(!h[sum])
	{
		h[sum] = true;
		ans++;
	}
	for(int i = n; i < nLen; ++i)
	{
		sum -= num[str[i - n]] * pow;
		sum = sum * nc + num[str[i]];
		if(!h[sum])
		{
			h[sum] = true;
			ans++;
		}
	}
	printf("%d\n", ans);
}
return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值