LCS算法找出两个字符串最长公共子串(C#实现)

算法原理:
(1) 将两个字符串分别以行和列组成矩阵。
(2) 计算每个节点行列字符是否相同,如相同则为 1。
(3) 通过找出值为 1 的最长对角线即可得到最长公共子串。

  人 民 共 和 时 代
中 0, 0, 0, 0, 0, 0
华 0, 0, 0, 0, 0, 0
人 1, 0, 0, 0, 0, 0
民 0, 1, 0, 0, 0, 0
共 0, 0, 1, 0, 0, 0
和 0, 0, 0, 1, 0, 0
国 0, 0, 0, 0, 0, 0

为进一步提升该算法,我们可以将字符相同节点(1)的值加上左上角(d[i-1, j-1])的值,这样即可获得最大公用子串的长度。如此一来只需以行号和最大值为条件即可截取最大子串。

  人 民 共 和 时 代
中 0, 0, 0, 0, 0, 0
华 0, 0, 0, 0, 0, 0
人 1, 0, 0, 0, 0, 0
民 0, 2, 0, 0, 0, 0
共 0, 0, 3, 0, 0, 0
和 0, 0, 0, 4, 0, 0
国 0, 0, 0, 0, 0, 0

算法实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LCS
{
    class Program
    {
        static void Main(string[] args)
        {
             try
            {
                Console.WriteLine("请输入目标字符串A:");
                string s = Console.ReadLine();
                Console.WriteLine("请输入目标字符串B:");
                string t = Console.ReadLine();
                string strReturn = LCS(t, s);
                if (string.IsNullOrEmpty(strReturn))
                {
                    Console.WriteLine("您输入的两个字符串没有找到最长的公共字符串.");
                }
                else
                {
                    Console.WriteLine("CLS算法为您找到的正常的公共字符串是:" + strReturn);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("error:"+ex.Message);
            }
        }

        /// 
        /// 最大公共字符串
        /// LCS算法
        /// 
        /// 字符串A
        /// 字符串B
        /// 
        private static string LCS(string str1, string str2)
        {
            if (str1 == str2)
                return str1;
            else if (String.IsNullOrWhiteSpace(str1) || String.IsNullOrWhiteSpace(str2))
                return null;

            var d = new int[str1.Length, str2.Length];
            var index = 0;
            var length = 0;

            for (int i = 0; i < str1.Length; i++)
            {
                for (int j = 0; j < str2.Length; j++)
                {
                    //左上角
                    var n = i - 1 >= 0 && j - 1 >= 0 ? d[i - 1, j - 1] : 0;

                    //当前节点值等于“左上角的值+1”:“0”
                    d[i, j] = str1[i] == str2[j] ? n + 1 : 0;

                    //如果是最大值,记录该值和行号
                    if (d[i, j] > length)
                    {
                        length = d[i, j];
                        index = i;
                    }
                }
            }

            return str1.Substring(index - length + 1, length);
        }
    }
}

你可能感兴趣的:(算法,C#,算法,c#)