Long Long Message

Problem's Link:http://poj.org/problem?id=2774


Mean:

求两个字符串的最长公共子串的长度。

analyse:

前面在学习后缀数组的时候已经做过一遍了,但是现在主攻字符串hash,再用字符串hash写一遍。

这题的思路是这样的:

1)取较短的串的长度作为high,然后二分答案(每次判断长度为mid=(low+high)>>1是否存在,如果存在就增加下界;不存在就缩小上界);

2)主要是对答案的判断(judge函数)。具体参看代码注释。

Time complexity:O(n)

Source code:

// Memory   Time
// 1347base 0MS
// by : Snarl_jsb
// 2014-10-04-21.16
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<climits>
#include<cmath>
#define ULL unsigned long long
using namespace std; string s1,s2;
int l1,l2,seed=131;
vector<ULL> hash;
bool judge(int x)
{
hash.clear();
ULL tmp=0;
for (int i = 0; i < x; i++)
{
tmp=tmp* seed + s1[i];
}
hash.push_back(tmp);
ULL base =1;
for (int i = 1; i < x; i++)
{
base *= seed;
}
for (int i = x; i < l1; i++)
{
tmp=(tmp*seed+s1[i])-base*s1[i-x]*seed;
hash.push_back(tmp);
}
sort(hash.begin(),hash.end());
ULL hashval = 0;
for (int i = 0; i < x; i++)
{
hashval = hashval * seed + s2[i];
}
if (binary_search(hash.begin(),hash.end(),hashval))
return 1;
for (int i = x; i < l2; i++)
{
hashval = (hashval-(s2[i-x])*base)*seed+s2[i];
if (binary_search(hash.begin(),hash.end(),hashval))
return 1;
}
return 0;
}
int main()
{
while (cin>>s1>>s2)
{
l1=s1.size();
l2=s2.size();
int ans = 0;
int high = min(l1,l2);
int low = 0; while (low <= high)
{
int mid = (low+high)>>1;
if (judge(mid))
{
ans = mid;
low = mid+1;
}
else
high = mid-1;
}
printf("%d\n",ans);
}
return 0;
}

注释代码:

// Memory   Time
// 1347k 0MS
// by : Snarl_jsb
// 2014-10-04-21.16
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<climits>
#include<cmath>
#define ULL unsigned long long
using namespace std; string s1,s2;
int l1,l2,seed=131;
vector<ULL> hash;
bool judge(int x)
{
hash.clear();//多组数据时不要忘了清空全局数组
//构造s1串的hash表
ULL tmp=0;
for (int i = 0; i < x; i++)
{
tmp=tmp* seed + s1[i];
}
hash.push_back(tmp);
ULL base =1;
for (int i = 1; i < x; i++)//求出到达x的base值
{
base *= seed;
}
for (int i = x; i < l1; i++)
{
tmp=(tmp*seed+s1[i])-base*s1[i-x]*seed;
hash.push_back(tmp);
}
//构造完毕
sort(hash.begin(),hash.end()); //二分查找加速,必需先排序
ULL hashval = 0;
for (int i = 0; i < x; i++)//求出s2串0到x的hash值
{
hashval = hashval * seed + s2[i];
}
if (binary_search(hash.begin(),hash.end(),hashval))//查找s2串0到x的hash值是否在s1串的hash表中
return 1;
for (int i = x; i < l2; i++)//如果上面的s2串0到x的hash值未匹配成功,这儿接着匹配s2串长度为x的hash值是否出现在s1串的hash表中
{
hashval = hashval*seed+s2[i]-s2[i-x]*base*seed;
if (binary_search(hash.begin(),hash.end(),hashval))
return 1;
}
return 0;
}
int main()
{
while (cin>>s1>>s2)
{
l1=s1.size();
l2=s2.size();
int ans = 0;
int low=0,high = min(l1,l2);
while (low <= high)//二分答案
{
int mid = (low+high)>>1;
if (judge(mid))//判断答案是否可行
{
ans = mid;
low = mid+1;
}
else
high = mid-1;
}
printf("%d\n",ans);
}
return 0;
}

  

字符串hash + 二分答案 - 求最长公共子串 --- poj 2774的更多相关文章

  1. 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message

    Language: Default Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 21 ...

  2. POJ 2774 Long Long Message (二分 + Hash 求最长公共子串)题解

    题意:求最长公共子串 思路:把两个串Hash,然后我们把短的作为LCS的最大可能值,然后二分长度,每次判断这样二分可不可以.判断时,先拿出第一个母串所有len长的子串,排序,然后枚举第二个母串len长 ...

  3. poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403

    题意:给出两个字符串,求最长公共子串的长度. 题解:首先将两个字符串连在一起,并在中间加一个特殊字符(字串中不存在的)切割,然后两个串的最长公共字串就变成了全部后缀的最长公共前缀.这时就要用到heig ...

  4. 求最长公共子串 Longest Common Subsequence

    最长公共子串 // Longest Common Subsequence 子串有别于子序列, 子串是连续的, 而子序列可以不连续 /*--------------------------------- ...

  5. 文本比较算法Ⅱ——Needleman/Wunsch算法的C++实现【求最长公共子串(不需要连续)】

    算法见:http://www.cnblogs.com/grenet/archive/2010/06/03/1750454.html 求最长公共子串(不需要连续) #include <stdio. ...

  6. poj2774 Long Long Message 后缀数组求最长公共子串

    题目链接:http://poj.org/problem?id=2774 这是一道很好的后缀数组的入门题目 题意:给你两个字符串,然后求这两个的字符串的最长连续的公共子串 一般用后缀数组解决的两个字符串 ...

  7. java求最长公共子串的长度

    1这道题目就是给定两个字符串,然后求这两个字符串的最长公共子串的最大长度,假设我的f()方法是来求两个字符串的最大公共子串,从头开始逐一比较,如果相等,则 继续调用这个方法,使得递归的长度+1,如果不 ...

  8. 利用后缀数组(suffix array)求最长公共子串(longest common substring)

    摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其 ...

  9. poj 2774 字符串哈希求最长公共子串

    Long Long Message #include <iostream> #include <algorithm> #include <cstdio> #incl ...

随机推荐

  1. .Net规则引擎介绍 - REngine

    规则引擎 规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策.接受数据输入,解释业务规则,并根据业务规则做出业务决策 ...

  2. 解决微信浏览器无法使用reload()刷新页面

    场景是这样子的,页面在初始化时有一个ajax请求,在页面上有一个按钮,点击的时候执行window.location.reload(),正常情况reload()后页面依然会向后台发出请求,但在安卓的微信 ...

  3. 结合仓库设计MVC控制器

    为了更高效的开发MVC项目,我们对控制器进行了在一次的封装,使得控制器能够获得很好的继承关系,并能以更少 的代码,实现Web项目的开发工作,整个控制器的设计思路如下所示.       从上图的设计里面 ...

  4. Hadoop 生态系统

    1.概述 最近收到一些同学和朋友的邮件,说能不能整理一下 Hadoop 生态圈的相关内容,然后分享一些,我觉得这是一个不错的提议,于是,花了一些业余时间整理了 Hadoop 的生态系统,并将其进行了归 ...

  5. 从今天起,记录CEF使用开发心得经验

    已经使用CEF来呈现桌面程序界面大半年了,从来没有写过相关博文.发现网上的中文资料甚至英文已经无法满足我的开发需求,不少问题只得自己探索.在此先谢过网络上各位CEF使用开发博文的贡献者,没有你们我也难 ...

  6. sqlite3基础

    要使用sqlite,首先需要添加库文件libsqlite3.dylib.当你搜索libsqlite3关键字时,会发现还有一个libsqlite3.0.dylib的库文件,这里还是建议添加libsqli ...

  7. MySQL数据库之数据类型BOOL/BOOLEAN与TINYINT测试总结

    From: http://database.51cto.com/art/201203/323863.htm 网络上很多人咨询mysql是否提供布尔类型?MySQL数据库确实提供布尔类型,此数据类型的关 ...

  8. 解决“iOS 7 app自动更新,无法在app中向用户展示更新内容”问题

    转自cocoachina iOS 7能在后台自动app,这对开发者来说和用户都很方便,但是还是有一些缺点.用户不会知道app本次更新的内容,除非他们上到app的App Store页面去查看.开发者也会 ...

  9. CentOS 7 上编译安装MySQL 5.6.23

    1.下载源码 wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.23.tar.gz 2.解压 tar zxvf mysql-5.6 ...

  10. CM: 如何自己build一个官方版本出来,使用官方release中的manifests.xml

    This can be accomplished in one of two ways: 1) Pull the file from your device:cd /your/repo/pathadb ...