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

相关文章

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Java使用正则提取字符串中的内容的详细步骤

《Java使用正则提取字符串中的内容的详细步骤》:本文主要介绍Java中使用正则表达式提取字符串内容的方法,通过Pattern和Matcher类实现,涵盖编译正则、查找匹配、分组捕获、数字与邮箱提... 目录1. 基础流程2. 关键方法说明3. 常见场景示例场景1:提取所有数字场景2:提取邮箱地址4. 高级

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图