第2部分 字符串算法(提高篇)--第1章 哈希和哈希表1457:Power Strings

本文探讨了如何利用哈希和哈希表解决POJ 2406问题,即确定字符串由多少个相同子字符串重复组成。通过计算字符串的hash值并进行取模操作,可以有效地判断字符串中连续部分的重复性。举例说明了计算过程,并解释了在计算过程中如何处理负值和取模的问题。
摘要由CSDN通过智能技术生成

1457:Power Strings

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 1280 通过数: 515
【题目描述】
原题来自:POJ 2406

给定若干个长度 ≤106 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab 则最多有 3 个 ab 连接而成。

【输入】
输入若干行,每行有一个字符串,字符串仅含英语字母。特别的,字符串可能为 . 即一个半角句号,此时输入结束。

【输出】
【输入样例】
abcd
aaaa
ababab
.
【输出样例】
1
4
3


思路:假设 b = 3,数的范围为0-63 (代码中实际情况是,b=131,mod = 1<<31,数据类型为unsigned long long)

对于字符串abcabc:

               index:  0      1      2           3           4         5

               arr:    a      b      c           a            b        c

               hash:  56      61     41          34          11        3    
               
                (计算公式:hash[i]=hash[i+1]*b+s1[i]-‘a‘+1)         这里面有个问题是:因为数的范围为0-63 ,最大为63,可能存在数的溢出,比如:

从左往右,a->c这一步,hash[2] = hash[3] * 3+‘c‘-‘a‘+1 =34 * 3+2+1= 105。105大于63,这么办?
在计算机中会自动取模(也就是取余数):105% 64=41。其他 hash值都是这么计算的,每步都会取余数的。
同样,power的计算也是如此:3 9 27 17(81%64) …
那么计算机怎么判断前三个字符(“abc”)与后三个字符(“abc”)相等呢?取模后计算会不会出现负值?
后三个字符:tmp0 = hash[3]-hash[6] * power[3] = 34 - 0 * 27 = 34
前三个字符:tmp1 = hash[0]-hash[3] * power[3] = 56 -34 * 27 = ? 。这里34* 27实际是(34* 27)%64=22,所以56-22=34。
所以tmp0=tmp1。(程序中用函数封装)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
const 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值