C#,求最长回文字符串的马拉车(Manacher)算法的源代码

本文主要是介绍C#,求最长回文字符串的马拉车(Manacher)算法的源代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、回文字符串(Palindromic String)

回文字符串(Palindromic String)是指前、后向读起来完全相同的字符串。

回文字符串除了答题似乎没有什么用处 :P

二、求解思路

求解字符串的回文子串的基本思路:

1、遍历每个位置;
2、先看有没有以位置i为中心的回文串(举例ABCBA)。所以我们要比较i+1和i-1是否相等,i+2和i-2是否相等,一直比较到字符串某一端点结束,或者中途发现不等的字符;
3、再看有没有以位置i为对称中心的回文串(举例ABBA)。所以我们要先看i和i+1等不等,如果等,那再看i-1和i+2是否相等,i-2和i+3是否相等,一直比较到字符串某一端点结束,或者中途发现不等的字符。

Manacher算法是一位名叫Manacher的人在1975年提出的一种算法,解决的问题是求最长回文子串。Manacher算法的核心思路就是利用之前求得的臂长( 即之前求出的Len值) 来减少时间复杂度,也就是说通过前面求出的Len值来加速求出当前下标i的 Len[i],快速求出所有的Len 值就是该算法的目的。

速度!

三、源代码

3.1 文本格式

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

namespace Legalsoft.Truffer.Algorithm
{
    // C# program to implement Manacher's Algorithm
    // This code is contributed by PrinciRaj1992
    public static class Palindromic_String
    {
        public static string Manacher(string text)
        {
            int N = text.Length;
            if (N == 0)
            {
                return "";
            }
            N = 2 * N + 1;

            int[] lengthArray = new int[N + 1];
            lengthArray[0] = 0;
            lengthArray[1] = 1;

            int centerPosition = 1;
            int centerRightPosition = 2;
            int currentRightPosition = 0;
            int currentLeftPosition;
            int maxLPSLength = 0;
            int maxLPSCenterPosition = 0;
            int start = -1;
            int end = -1;
            int diff = -1;

            // Uncomment it to print LPS Length array
            for (currentRightPosition = 2; currentRightPosition < N; currentRightPosition++)
            {
                // get currentLeftPosition iMirror for currentRightPosition i
                currentLeftPosition = 2 * centerPosition - currentRightPosition;
                lengthArray[currentRightPosition] = 0;
                diff = centerRightPosition - currentRightPosition;

                // 如果 currentRightPosition 范围内
                if (diff > 0)
                {
                    lengthArray[currentRightPosition] = Math.Min(lengthArray[currentLeftPosition], diff);
                }

                // 尝试扩展以 currentRightPosition i为中心的回文。
                // 对于奇数位置,我们比较字符,如果匹配,则将LPS长度增加1。
                // 即使是位置,我们只是将LPS增加1,而不进行任何字符比较。
                while (((currentRightPosition + lengthArray[currentRightPosition]) + 1 < N && (currentRightPosition - lengthArray[currentRightPosition]) > 0) &&
                    (((currentRightPosition + lengthArray[currentRightPosition] + 1) % 2 == 0) || 
                    (text[(currentRightPosition + lengthArray[currentRightPosition] + 1) / 2] == text[(currentRightPosition - lengthArray[currentRightPosition] - 1) / 2])))
                {
                    lengthArray[currentRightPosition]++;
                }

                // 重新计算maxLPSLength
                if (lengthArray[currentRightPosition] > maxLPSLength)
                {
                    maxLPSLength = lengthArray[currentRightPosition];
                    maxLPSCenterPosition = currentRightPosition;
                }

                // 如果以currentRightPosition为中心的回文扩展到centerRightPosition之外,
                // 根据扩展的回文调整centerPosition
                if (currentRightPosition + lengthArray[currentRightPosition] > centerRightPosition)
                {
                    centerPosition = currentRightPosition;
                    centerRightPosition = currentRightPosition + lengthArray[currentRightPosition];
                }
            }

            start = (maxLPSCenterPosition - maxLPSLength) / 2;
            end = start + maxLPSLength - 1;
            if (end > start)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = start; i <= end; i++)
                {
                    sb.Append(text.Substring(i, 1));
                }
                return sb.ToString();
            }
            return "";
        }
    }
}
 

-------------------------------------------------------

POWER BY TRUFFER.CN

3.2 代码格式

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{// C# program to implement Manacher's Algorithm// This code is contributed by PrinciRaj1992public static class Palindromic_String{public static string Manacher(string text){int N = text.Length;if (N == 0){return "";}N = 2 * N + 1;int[] lengthArray = new int[N + 1];lengthArray[0] = 0;lengthArray[1] = 1;int centerPosition = 1;int centerRightPosition = 2;int currentRightPosition = 0;int currentLeftPosition;int maxLPSLength = 0;int maxLPSCenterPosition = 0;int start = -1;int end = -1;int diff = -1;// Uncomment it to print LPS Length arrayfor (currentRightPosition = 2; currentRightPosition < N; currentRightPosition++){// get currentLeftPosition iMirror for currentRightPosition icurrentLeftPosition = 2 * centerPosition - currentRightPosition;lengthArray[currentRightPosition] = 0;diff = centerRightPosition - currentRightPosition;// 如果 currentRightPosition 范围内if (diff > 0){lengthArray[currentRightPosition] = Math.Min(lengthArray[currentLeftPosition], diff);}// 尝试扩展以 currentRightPosition i为中心的回文。// 对于奇数位置,我们比较字符,如果匹配,则将LPS长度增加1。// 即使是位置,我们只是将LPS增加1,而不进行任何字符比较。while (((currentRightPosition + lengthArray[currentRightPosition]) + 1 < N && (currentRightPosition - lengthArray[currentRightPosition]) > 0) &&(((currentRightPosition + lengthArray[currentRightPosition] + 1) % 2 == 0) || (text[(currentRightPosition + lengthArray[currentRightPosition] + 1) / 2] == text[(currentRightPosition - lengthArray[currentRightPosition] - 1) / 2]))){lengthArray[currentRightPosition]++;}// 重新计算maxLPSLengthif (lengthArray[currentRightPosition] > maxLPSLength){maxLPSLength = lengthArray[currentRightPosition];maxLPSCenterPosition = currentRightPosition;}// 如果以currentRightPosition为中心的回文扩展到centerRightPosition之外,// 根据扩展的回文调整centerPositionif (currentRightPosition + lengthArray[currentRightPosition] > centerRightPosition){centerPosition = currentRightPosition;centerRightPosition = currentRightPosition + lengthArray[currentRightPosition];}}start = (maxLPSCenterPosition - maxLPSLength) / 2;end = start + maxLPSLength - 1;if (end > start){StringBuilder sb = new StringBuilder();for (int i = start; i <= end; i++){sb.Append(text.Substring(i, 1));}return sb.ToString();}return "";}}
}

这篇关于C#,求最长回文字符串的马拉车(Manacher)算法的源代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605790

相关文章

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函