zoukankan      html  css  js  c++  java
  • Hash技术初涉

    例题POJ-2406

    解决思路链接

    Hash解决代码

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    char s[1001000]; // 输入字串
    int mod=10009; //模
    int len,k=131; //s 的长度为 len
    ll hash[1001000]; // hash[i]存储以第 i 个字符为尾的前缀的散列值
    
    ll cal(int x,ll y) //计算和返回 y的x次方 % mod 的结果值
    {
    	ll re=1; //结果值初始化
    	while(x) //分析次幂 x 的每一个二进制位
    	{
    		if(x&1) re=(re*y)%mod; //若当前位为 1,则累乘当前位的权并取模
    		x>>=1;y=(y*y)%mod; //次幂 x 右移一位,计算该位的权后取模
    	}
    	return re; //返回结果值
    }
    
    bool check(int x) //若所有长度为 x 的相邻子串对应的散列函数值相等,则返回 true;否则返回 false
    {
    	ll cc=cal(x,(ll)k); //计算 kx % mod
    	for(int i=(x<<1);i<=len;i+=x) //搜索字符 i(2*x≤i≤len)。若任一长度 i 的子串 si-x+1…i的散列值不等于长度为 x 的前缀的散列值,则返回 fase;否则返回 true
    	{
    		if((hash[i]-(hash[i-x]*cc)%mod+mod)%mod!=hash[x])return false;
    	}
    	return true;
    }
    
    
    int main()
    {
    	//freopen("in.txt","r",stdin);
    	while(1) 
    	{
    		scanf("%s",s+1); //输入字串
    		len=strlen(s+1); //计算字串长度
    		if(len==1 && s[1]=='.') return 0;//返回空串的次幂 0
    		for(int i=1;i<=len;i++) //计算所有前缀的散列值
    		{
    			hash[i]=(hash[i-1]*k+s[i])%mod;
    		}
    		for(int i=1;i<=len;i++) //枚举可能的子串长度
    		{
    			if(len%i==0 && check(i)) //若 s 能够划分出长度 i 的子串且所有相邻子串的散列值相等,则输出子串个数,并退出 for 循环
    			{
    				printf("%d
    ",len/i);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    

    OK

  • 相关阅读:
    2/4 关于 Vue.js 中 this.$nextTick 的个人简单解释
    2/3 初次搭建 Vue 项目遇到的问题汇总
    前端中常见的布局
    如何判断一个变量是否为数组(isArray)
    ubuntu下安装截图工具
    正向代理、反向代理
    javascript中的基本数据类型
    css3 中的渐变
    javascript中的toString()
    ubuntu下面安装nodejs
  • 原文地址:https://www.cnblogs.com/savennist/p/13412051.html
Copyright © 2011-2022 走看看