動態規劃-最長公共子序列

何畢之發表於2018-06-24
using System;

namespace 最長公共子序列
{
    class Program
    {

        public static readonly string str1 = "abacadba";
        public static readonly string str2 = "abcdabcd";
        public static int[,] map = new int[str1.Length + 1, str2.Length + 1];

        static void Main(string[] args)
        {
            LCS();

            Console.WriteLine("行表示str1,列表示str2:");
            DisplayMap();

            Console.WriteLine();
            DisplayRes();

            Console.ReadKey();
        }

        /// <summary>
        /// LCS演算法
        /// </summary>
        static void LCS()
        {
            //初始化矩陣內所有元素為0
            for (int i = 0; i < str1.Length + 1; i++)
            {
                for (int j = 0; j < str2.Length + 1; j++)
                {
                    map[i, j] = 0;
                }
            }


            for (int i = 1; i < str1.Length + 1; i++)
            {
                for (int j = 1; j < str2.Length + 1; j++)
                {
                    //若str1的第i個元素和str2的第j個元素相等 則map[i,j]等於 map中當前單元格左邊或者上面較大的值+1
                    //若str1的第i個元素和str2的第j個元素不相等 則map[i,j]等於 map中當前單元格左邊或者上面較大的值
                    if (str1[i - 1] == str2[j - 1])
                        map[i, j] = Math.Max(map[i - 1, j], map[i, j - 1]) + 1;
                    else
                        map[i, j] = Math.Max(map[i - 1, j], map[i, j - 1]);
                }
            }
        }
        /// <summary>
        /// 顯示LCS演算法運算後的MAP矩陣
        /// </summary>
        static void DisplayMap()
        {
            Console.Write("    ");
            for (int i = 0; i < str2.Length; i++)
            {
                Console.Write("  " + str2[i]);
            }
            Console.Write("\r\n");

            for (int i = 0; i < str1.Length + 1; i++)
            {
                if (i > 0 && i < str1.Length + 1)
                    Console.Write(str1[i - 1] + "  ");
                else
                    Console.Write("   ");
                for (int j = 0; j < str2.Length + 1; j++)
                {
                    Console.Write(map[i, j] + "  ");
                }
                Console.Write("\r\n");
            }
        }

        /// <summary>
        /// 顯示LCS長度和結果
        /// </summary>
        static void DisplayRes()
        {
            Console.WriteLine("str1和str2的最長公共子序列長度是:" + map[str1.Length, str2.Length]);
            Console.Write("str1和str2的最長公共子序列是:");
            int flag = map[0, 0];
            for (int i = 1; i < str1.Length + 1; i++)
            {
                for (int j = 1; j < str2.Length + 1; j++)
                {
                    if (map[i, j] > Math.Max(map[i - 1, j], map[i, j - 1]) && map[i, j] > flag)
                    {
                        Console.Write(str1[i - 1]);
                        flag = map[i, j];
                        break;
                    }
                }
            }
        }
    }
}


相關文章