`
lzj0470
  • 浏览: 1276929 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

LCS算法

阅读更多
当年微软面试时要求我写一个返回两个任意字串中最大公共串的函数,即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算法java源代码

    根据LCS算法取出最长公用字符串,实现字符串比较

    最长子序列LCS算法

    最长子序列LCS算法,用于处理最长公共字串问题。 两个序列的LCS问题包含两个序列的前缀的LCS,因此,LCS问题具有最优子结构性质。在设计递归算法时,不难看出递归算法具有子问题重叠的性质。   设C[i,j]C[i,j]...

    C#写的LCS算法

    LCS算法的核心在于找到两个序列在不考虑顺序的情况下,最长的共享子序列。这个子序列并不一定是连续的,但它是两个原始序列中的一个子集。例如,序列"ABCBDAB"和"BDCAB"的LCS是"BCAB"。 C#实现LCS算法通常会采用...

    lcs.rar_LCS_LCS算法_Lcs.rar_最长公共子序列

    LCS算法旨在找到两个给定序列之间的最长子序列,这个子序列并不需要在原序列中连续出现,但必须保持原有的顺序。 LCS算法的基本思想是采用动态规划来解决。动态规划是一种将复杂问题分解为更小的子问题,并存储这些...

    LCS.zip_LCS算法

    下面我们将深入探讨LCS算法的原理、实现方式以及它的应用。 ### 1. LCS算法定义 给定两个字符串S1和S2,LCS是指存在于S1和S2中的一个子序列,该子序列不是S1或S2的子串,但与两者都相同,且长度最长。例如,对于...

    LCS算法(连续)

    在本项目中,LCS算法被实现为连续问题的解决方案,使用了C++编程语言,旨在提供稳定且高效的性能。** LCS算法的基本思想是通过动态规划来解决。假设我们有两个字符串X和Y,我们要找它们的最长公共子序列。首先,...

    DELPHI 计算两个字符串相似度 LCS算法(附源代码)

    LCS算法是一种找出两个序列中最长的相同子序列的算法,它不考虑子序列的顺序,对于字符串而言,就是找到最长的相同子字符串。 首先,我们需要理解LCS算法的基本思想。假设我们有两个字符串S1和S2,LCS算法会找到S1...

    实验九lcs算法.doc

    本实验报告主要围绕LCS算法进行深入理解和实现,通过分析和设计,旨在让学生掌握动态规划的核心思想。 LCS问题的基本定义是:给定两个序列X和Y,找出它们的最长公共子序列,这个子序列不必连续,但要求字符顺序与原...

    带有 LCS算法的图像差异工具_rust_代码_下载

    【标题】中的“带有 LCS 算法的图像差异工具”指的是使用了 Longest Common Subsequence(最长公共子序列)算法来处理图像差异的工具。LCS 算法是一种在计算机科学中广泛应用于比较序列相似性的算法,不仅在文本编辑...

    求最长公共子序列的LCS算法

    实现了求最长公共子序列的算法,内容简单易懂,代码也很短

    lcs算法详解.pdf

    "LCS算法详解.pdf" LCS(Longest Common Subsequence)问题是计算机科学中一个经典的问题,它是指在两个或多个序列中找到最长的公共子序列。这个问题的解决思路有穷举搜索法和动态规划算法两种。 穷举搜索法是最...

    行业分类-设备装置-一种节省内存的LCS算法.zip

    《一种节省内存的LCS算法》 在信息技术领域,特别是在数据处理和算法设计中,Longest Common Subsequence(最长公共子序列,简称LCS)是一个经典的计算机科学问题。LCS算法广泛应用于序列比对、生物信息学、文本...

    LCS算法源码

    在这里,我们将深入探讨LCS算法的基本原理、实现方式以及其在实际问题中的应用。 LCS算法的核心思想是通过动态规划来解决问题。假设我们有两个序列X和Y,我们需要找到它们的最长公共子序列。一个子序列是从原序列中...

    最长公共子序列(LCS)算法源代码和实验报告

    LCS算法的核心在于动态规划。我们可以使用二维数组L[i][j]来存储两个序列X和Y前i个字符与前j个字符的最长公共子序列的长度。基本的递推关系如下: 1. 如果X[i-1] = Y[j-1],则L[i][j] = L[i-1][j-1] + 1,表示在...

    最长公共子序列LCS算法

    最长公共子序列(Longest Common ...通过学习和讨论LCS算法,我们可以深入了解动态规划的运用,提高解决序列比较问题的能力。同时,也可以将其扩展到处理多个序列的LCS问题,例如找到多个序列的最长公共子序列。

    算法导论LCS

    LCS算法是一种经典的动态规划问题,其目标是在两个或多个序列中找到最长的相同子序列。这里说的“子序列”是指通过删除原序列中的某些元素(但保持元素顺序不变)得到的序列。LCS问题广泛应用于文本比较、生物信息学...

    C# LCS 文本比较器

    本文将详细介绍LCS算法及其在C#中的实现,以及如何通过该项目进行文本比较。 LCS算法是一种经典的计算机科学问题,其目标是在两个序列中找到最长的子序列,该子序列同时存在于两个序列中,但并不要求连续。在文本...

    带有 LCS 算法的 图像差异工具_rust_代码_下载

    lcs 图像差异 带有 LCS 算法的图像差异库和工具

    基于GPU的LCS算法加速机制研究与实现.pdf

    基于GPU的LCS算法加速机制研究与实现.pdf

    最长公共子序列(LCS)的算法C++实现-已用模板类封装

    LCS算法的精髓就是动态规划,序列其实不仅限于字符序列,因此我用模版类对该算法进行了封装,里面提供了尽量方便的函数来进行该算法的使用,该实现并不追求速度最快化,而是尽量让该算法类能支持重用,若发现算法有...

Global site tag (gtag.js) - Google Analytics