当年微软面试时要求我写一个返回两个任意字串中最大公共串的函数,即abcdef 和 qcfbcc 返回值为bc语言不限
我的思路:
1.确定一个串为长串,另一个串为短串,在长串中找短串(长串中最长的公串可能性就是短串本身)
2.顺序确定短串中的每个字符是否在长串中出现(先做一个预定位)
3.如满足条件2,即短串中某个字符在长串中出现,在长串中试图找从这个字符起到短串末尾止的整个串
4.如果不满足条件3,短串末尾递减1个字符,直到找到此次字符出现的最大长度(至少是一个字符)
5.把此次找到的字符长度,与临时变量比较,如果此次长度大于历史长度,重赋值返回值
6.重复2-5,直到短串末尾
我的实现:
C#版
public static string GetPubMaxString(string Value1,string Value2)
{
string result=null,stmp;
int maxLen=0;
if (Value2.Length>Value1.Length)//确保Value1是长串
{
stmp=Value1;
Value1=Value2;
Value2=stmp;
}
for (int i=0;i<Value2.Length;i++)
{
if (Value1.IndexOf(Value2[i])>-1)//长串中依次判断短串的每个字符是否出现
{
stmp=Value2.Substring(i);//截取短串中出现字符到末尾存入变量
for (int ii=stmp.Length;ii>0;ii--)
{
if (Value1.IndexOf(stmp.Substring(0,ii))>-1)//长串中依次判断短串变量的左取子串是否出现
if (ii>maxLen) //如果出现并且此串长度大于上串的长度
{
result=stmp.Substring(0,ii);
maxLen=ii;
}
}
}
}
return result;
}
此算法的缺点是需要用很多次Substring方法,而此方式是需要创建新的string对象的,所以系统资源消耗比较大
后来在CSDN上看到了soholi(天涯孤棹) 网友实现上更简洁的算法:
public static string GetLargePublicString(string A,string B)
{
string shortString = A.Length > B.Length ? B : A;//取较短者;
string longString = A.Length > B.Length ? A : B;//取较长者;
for (int i = shortString.Length; i > 0; i--)//长度递减
{
for (int j = 0; j <= shortString.Length - i; j++)//位置递增
{
if (longString.IndexOf(shortString.Substring(j,i)) != -1)
{
return shortString.Substring(j, i);
}
}
}
return string.Empty;
}
真是可以算是很优雅简洁的实现,两个实现主要区别就在于,我那个GetPubMaxString是先定位确实存在的一个字符后,才开始找这个一定存 在,但长度未知的公共串,而网友soholi(天涯孤棹) 的GetLargePublicString则是在长串遍历整个短串的组合。
最近和薛 强兄吃饭聊起来,他给出了LCS(Longest Common Subsequence)算法的正解。其实早有牛人针对这一问题给出了标准算法了,一试之下,确实还是性能最好的方式。完全不需要用.net String对象所消耗的开销,而是语言无关的传统数组比较的方式,在其他语言也有借鉴意义,看来这也是传统的C、C++具有顽强生命力的原因所在之一 吧,算法的魅力与力量确实还是博大精深啊!
算法如下:
public static string Compare(string str1, string str2)
{
if (str1.Length < str2.Length)
{
string strTemp = str1;
str1 = str2;
str2 = strTemp;
}
int[] sign = new int[str1.Length];
int length = 0;
int end = 0;
for (int i = 0; i < str2.Length; i++)
{
for (int j = str1.Length - 1; j >= 0; j-- )
{
if (str2[i] == str1[j])
{
if (i == 0 || j == 0)
sign[j] = 1;
else
sign[j] = sign[j - 1] + 1;
}
else
sign[j] = 0;
if (sign[j] > length)
{
length = sign[j];
end = j;
}
}
}
return str1.Substring(end - length + 1, length);
}
分享到:
相关推荐
根据LCS算法取出最长公用字符串,实现字符串比较
最长公共子序列,即LCS算法,用C#写的LCS算法实现过程
最长子序列LCS算法,用于处理最长公共字串问题。 两个序列的LCS问题包含两个序列的前缀的LCS,因此,LCS问题具有最优子结构性质。在设计递归算法时,不难看出递归算法具有子问题重叠的性质。 设C[i,j]C[i,j]...
关于LCS(最长公共子序列)算法的实现~ 自己测试通过的
LCS算法源码
lcs算法详解.pdf
实现了求最长公共子序列的算法,内容简单易懂,代码也很短
LCS算法的精髓就是动态规划,序列其实不仅限于字符序列,因此我用模版类对该算法进行了封装,里面提供了尽量方便的函数来进行该算法的使用,该实现并不追求速度最快化,而是尽量让该算法类能支持重用,若发现算法有...
最长公共字串算法,为算法导论上的算法,可以运行,运行时间为O(mn)
LCS(Longest common string)连续问题的求解,C++编写,稳定,高效.
最长公共子序列算法LCS实现。任意输入两个字符串,通过此算法可以找到最长的公共子序列。
LCS算法的简单java实现,可以一起讨论学习
lcs 图像差异 带有 LCS 算法的图像差异库和工具
最长公共子序列(Longest Common Subsequence LCS)是从给定的两个序列X和Y中取出尽可能多的一部分字符,按照它们在原序列排列的先后次序排列得到。
比较两个字符串的相似度,利用LCS算法计算出两个字符串的最长公序列,根据最长公序列得出相似度,例如: 字符串1:1234 字符串2:51234,则他们的相似度为:4*2/(4+5)。
lcs 图像差异 带有 LCS 算法的图像差异库和工具
算法导论 DNA的匹配算法 是当年苦学力行的结果希望有用。
求解最长公共子序列LCS的算法,亲测可用,快来下载吧
用于求解两个串的最长公共子序列,输入两个字符串,从中找到最长的公共子序列。
基于GPU的LCS算法加速机制研究与实现.pdf