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 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 "";
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/319754.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# 图解教程 第5版 —— 第25章 反射和特性

文章目录 25.1 元数据和反射25.2 Type 类25.3 获取 Type 对象25.4 什么是特性25.5 应用特性25.6 预定义的保留特性25.6.1 Obsolete 特性25.6.2 Conditional 特性25.6.3 调用者信息特性25.6.4 DebuggerStepThrough 特性25.6.5 其他预定义特性 25.7 关于应用特性的更多内容25.7.1…

springboot怎样设置全局的traceId(包括MQ)

一、Controller打印TraceId 1、拦截所有的controller&#xff0c;输入输出将traceId放入MDC中&#xff1a; package com.perkins.ebicycle.mobile.trace;import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.stream.Collectors;import…

深思熟虑可能性模型介绍与使用

深思熟虑可能性模型介绍与使用 如何联系我 作者&#xff1a;鲁伟林 邮箱&#xff1a;thinking_fioa163.com或vlinyes163.com 版权声明&#xff1a;文章和记录为个人所有&#xff0c;如果转载或个人学习&#xff0c;需注明出处&#xff0c;不得用于商业盈利行为。 背景 20…

操作系统详解(5.1)——信号(Signal)的相关题目

系列文章&#xff1a; 操作系统详解(1)——操作系统的作用 操作系统详解(2)——异常处理(Exception) 操作系统详解(3)——进程、并发和并行 操作系统详解(4)——进程控制(fork, waitpid, sleep, execve) 操作系统详解(5)——信号(Signal) 文章目录 题目第一问第二问第三问 题目…

ES搜索的安装以及常用的增删改查操作(已经写好json文件,可以直接使用)

1.es的下载 https://www.elastic.co/cn/downloads/past-releases 2.elasticsearch安装及配置&#xff0c;遇到9200访问不了以及中文乱码&#xff0c;能访问了却要账户密码等问题 Elasticsearch启动后访问9200失败_http://localhost:9200无返回值-CSDN博客 3.开启es服务&#x…

Qat++,轻量级开源C++ Web框架

目录 一.简介 二.编译Oat 1.环境 2.编译/安装 三.试用 1.创建一个 CMake 项目 2.自定义客户端请求响应 3.将请求Router到服务器 4.用浏览器验证 一.简介 Oat是一个面向C的现代Web框架 官网地址&#xff1a;https://oatpp.io github地址&#xff1a;https://github.co…

Error: L6218E: Undefined symbol 系列错误汇总 (referred from main.o)

传送门 错误1&#xff1a; Undefined symbol(referred from main.o)错误2&#xff1a;Undefined_symbol _use_two_region memory 错误1&#xff1a; Undefined symbol(referred from main.o) Cube_GPIO\Cube_GPIO.axf: Error: L6218E: Undefined symbol LED_GPIO_Init (referr…

15个为你的品牌增加曝光的维基百科推广方法-华媒舍

维基百科是全球最大的免费在线百科全书&#xff0c;拥有庞大的用户群体和高质量的内容。在如今竞争激烈的市场中&#xff0c;利用维基百科推广品牌和增加曝光度已成为许多企业的重要策略。本文将介绍15种方法&#xff0c;帮助你有效地利用维基百科推广品牌&#xff0c;提升曝光…

GPT编程:运行第一个聊天程序

环境搭建 很多机器学习框架和类库都是使用Python编写的&#xff0c;OpenAI提供的很多例子也是Python编写的&#xff0c;所以为了方便学习&#xff0c;我们这个教程也使用Python。 Python环境搭建 Python环境搭建有很多种方法&#xff0c;我们这里需要使用 Python 3.10 的环境…

浅谈对Mybatis的理解

一、Mybatis的概述 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;由谷歌托管&#xff0c;并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是支持普通SQL查询&#xff0c;存储过程和高级映射的优…

ssm基于Web的课堂管理系统设计与实现论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

数据库(1)

目录 1.什么是数据库 1.1.数据 1.2.数据库 1.3 常见数据库 1.3.1 关系型数据库 1.3.2 非关系型数据库 2.mysql概述 ​编辑 **3.MySQL本地仓库安装 在Linux端操作 4.MySQL网络安装 **方法一&#xff1a;RPM捆绑包 下载安装RPM捆绑包&#xff1a; 在windows端操作&a…

开箱即用的企业级前后端分离【.NET Core6.0 Api + Vue 2.x + RBAC】权限框架-Blog.Core

前言 今天要给大家推荐一个开箱即用的企业级前后端分离【.NET Core6.0 Api Vue 2.x RBAC】权限框架&#xff08;提高生产效率&#xff0c;快速开发就选它&#xff09;&#xff1a;Blog.Core。 推荐原因 Blog.Core通过详细的文章和视频讲解&#xff0c;将知识点各个击破&…

element表格数据,表头上(下)角标,html字符串渲染

1. 问题描述 在动态渲染的element表格中&#xff0c;表头和表中数据是一个含有html的字符串&#xff0c;需要渲染 2. 效果 3. 代码 const columns ref([{ text: 差值<sub>-3</sub> / 10<sup>-6</sup>℃<sup>-1</sup>, value: aallowEr…

三菱FX系列PLC定长切割控制(线缆裁切)

三菱PLC绝对定位指令DDRVA实现往复运动控制详细介绍请查看下面文章链接&#xff1a; https://rxxw-control.blog.csdn.net/article/details/135570157https://rxxw-control.blog.csdn.net/article/details/135570157这篇博客我们介绍线缆行业的定长切割控制相关算法。 未完待…

Xmind 网页端登录及多端同步

好久没用 Xmind 了&#xff0c;前几天登录网页端突然发现没办法登录了&#xff0c;总是跳转到 Xmind AI 页面。本以为他们不再支持网页端了&#xff0c;后来看提示才知道只是迁移到了新的网址&#xff0c;由原来的 xmind.works 现在改成了的 xmind.ai。又花费好长时间才重新登录…

Vue3 移动端自适应方案postcss-px-to-viewport

我的环境 依赖名版本pnpm8.14.0Node16.20.1Vue3.3Vite5.0.8 一、安装 pnpm install postcss-px-to-viewport1.1.1 --save-dev 二、配置 vite.config.ts import postcsspxtoviewport from postcss-px-to-viewportexport default defineConfig({css: {postcss: {plugins: [p…

【HarmonyOS】网络数据请求连接与数据持久化操作

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…

QT获取程序编译时间与当前时间的区别及应用场景

一.获取编译时间与当前时间的区别 1.编译日期时间&#xff1a;这个信息通常用于标识某个源代码文件或整个应用程序的编译时间&#xff0c;程序一旦编译出来不会再改变&#xff0c;通常用于记录或跟踪代码的版本和更改历史。 2.运行当前日期时间&#xff1a;这是指程序在运行时…

ssm基于web的电影购票系统+vue论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统电影购票信息管理难度大&#xff0c;容错率低&#xff0c…
最新文章