字符串与算法题详解:最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密

前言

在编程题训练中,字符串相关的题目非常常见。本文将结合几个典型的例题,详细解析它们的解题思路和实现方式,帮助初学者循序渐进地掌握常用技巧。


一、最长回文子串问题

什么是回文串?

回文串(Palindrome)就是正读和反读相同的字符串,例如:

  • ABA 是回文串
  • ABBA 也是回文串
  • ABC 不是回文串

思路解析

要找出一个字符串中最长的回文子串长度,常见方法有两种:

  1. 中心扩展法

    • 枚举每一个字符,向两边扩展,判断是否对称。
    • 分为两类:奇数长度(如 ABA)、偶数长度(如 ABBA)。
  2. 字符串扩展法(Manacher 算法思想)

    • 在字符串中插入特殊字符(如 #),统一处理奇数和偶数回文的情况。

代码实现(中心扩展法)

#include <iostream>
#include <string>
using namespace std;int longestPalindrome(string s) {int n = s.size();int maxLen = 1;for (int i = 0; i < n; i++) {// 奇数回文int l = i, r = i;while (l >= 0 && r < n && s[l] == s[r]) {maxLen = max(maxLen, r - l + 1);l--, r++;}// 偶数回文l = i, r = i + 1;while (l >= 0 && r < n && s[l] == s[r]) {maxLen = max(maxLen, r - l + 1);l--, r++;}}return maxLen;
}int main() {string s;cin >> s;cout << longestPalindrome(s) << endl;
}

示例

输入:

babad

输出:

3   // 最长回文子串是 "bab" 或 "aba"

好的,你提到的 字符串扩展法(Manacher 算法思想) 是解决最长回文子串问题的经典算法。下面我帮你详细补充到教程里。


二、字符串扩展法(Manacher 算法思想)

核心思路

在使用中心扩展法时,我们需要分别处理:

  • 奇数长度回文串(如 ABA
  • 偶数长度回文串(如 ABBA

为了统一处理,可以在字符串中插入特殊字符(例如 #),让所有回文子串都变成奇数长度
比如原始字符串 abba,扩展后变成:

# a # b # b # a #

这样:

  • 原本的 abba(偶数回文)变成了 #a#b#b#a#,长度为奇数;
  • 原本的 aba(奇数回文)变成了 #a#b#a#,仍然是奇数。

这样就可以只写一份扩展逻辑,统一处理。

Manacher 算法原理
  1. 扩展字符串:在每个字符之间加入 #,并在首尾加上边界字符。
    例如:abba → ^#a#b#b#a#$
    (这里的 ^$ 是哨兵字符,防止越界)

  2. 维护回文半径数组 P

    • P[i] 表示以位置 i 为中心的回文半径(不含中心)。
    • 例如 P[i] = 3,表示回文子串长度是 2*3+1=7
  3. 利用对称性加速

    • 如果当前位置 i 在已知的最大回文右边界 R 内,那么 P[i] 可以通过对称点的结果推导。
    • 否则就从中心向两边扩展。
  4. 求解最大值

    • 最长回文子串的长度就是 max(P[i]) - 1(因为扩展时多加了 #)。
代码实现(C++)
#include <iostream>
#include <string>
#include <vector>
using namespace std;string preprocess(const string &s) {string t = "^";for (char c : s) {t += "#" + string(1, c);}t += "#$";return t;
}int longestPalindrome(string s) {string t = preprocess(s);int n = t.size();vector<int> P(n, 0);int C = 0, R = 0; // C: 当前回文中心, R: 当前回文最右端for (int i = 1; i < n - 1; i++) {int mirror = 2 * C - i; // i 关于中心 C 的对称点if (i < R)P[i] = min(R - i, P[mirror]);// 中心扩展while (t[i + 1 + P[i]] == t[i - 1 - P[i]])P[i]++;// 如果扩展后超过了 R,则更新中心和右边界if (i + P[i] > R) {C = i;R = i + P[i];}}// 找到最大回文半径int maxLen = 0;for (int len : P)maxLen = max(maxLen, len);return maxLen;
}int main() {string s;cin >> s;cout << longestPalindrome(s) << endl;
}
示例

输入:

abba

扩展后:

^#a#b#b#a#$

最终输出:

4   // 最长回文子串是 "abba"

方法对比
方法时间复杂度思路适用场景
中心扩展法O(n²)枚举中心点,向两边扩展数据量小
Manacher 算法O(n)扩展字符串 + 回文半径数组大数据量

二、整数与 IP 地址的转换

基本原理

  • IP 地址由四个数字组成(如 10.0.3.193),每个数字占 8 位,总共 32 位。

  • 可以将其转化为一个 32 位整数。

  • 例如:

    10.0.3.193 → (10 << 24) + (0 << 16) + (3 << 8) + 193
    

代码实现

#include <iostream>
using namespace std;int main() {unsigned int a, b, c, d;char dot;cin >> a >> dot >> b >> dot >> c >> dot >> d;unsigned int ip = (a << 24) + (b << 16) + (c << 8) + d;cout << ip << endl;unsigned int num;cin >> num;cout << ((num >> 24) & 255) << "."<< ((num >> 16) & 255) << "."<< ((num >> 8) & 255) << "."<< (num & 255) << endl;
}

三、字符串排序

题目解析

给定一个字符串,要求按 ASCII 值升序排序

代码实现

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;int main() {string s;cin >> s;sort(s.begin(), s.end());cout << s << endl;
}

示例

输入:

dcba321

输出:

123abcd

四、蛇形矩阵(找规律问题)

问题描述

输入一个整数 n,构造一个 n × n 的蛇形矩阵,只输出上三角部分。

例如 n = 5 时:

1  3  6  10 15
2  5  9  14
4  8  13
7  12
11

思路

  • 第 1 行输出 1 开始,每个元素与前一个差值依次增加。
  • 每行输出的数字个数递减。

代码实现

#include <iostream>
using namespace std;int main() {int n;cin >> n;for (int i = 1; i <= n; i++) {int num = i;for (int j = i; j <= n; j++) {cout << num << " ";num += j;}cout << endl;}
}

五、字符串加密

加密规则

  1. 选择一个单词作为密钥,去掉重复字母。
  2. 用密钥替换字母表前缀,构造加密字母表。
  3. 明文中的每个字母替换为加密表对应字母。

示例

密钥:attack
明文:attack
加密:txyz...

代码实现

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;int main() {string key, text;cin >> key >> text;string dict;bool used[26] = {false};for (char c : key) {if (!used[c - 'a']) {dict += c;used[c - 'a'] = true;}}for (char c = 'a'; c <= 'z'; c++) {if (!used[c - 'a']) dict += c;}unordered_map<char, char> mp;for (int i = 0; i < 26; i++) {mp['a' + i] = dict[i];}for (char c : text) {if (islower(c)) cout << mp[c];else if (isupper(c)) cout << (char)toupper(mp[tolower(c)]);else cout << c;}cout << endl;
}

总结

本文从几个典型题目出发,系统性讲解了字符串相关的算法题:

  • 最长回文子串:中心扩展法、字符串扩展。
  • IP 地址与整数转换:移位运算与掩码处理。
  • 字符串排序:利用 sort
  • 蛇形矩阵:数学找规律。
  • 字符串加密:构造映射表。

掌握这些题目的思路和实现,可以帮助我们快速解决更多字符串相关问题。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从协同设计到绿色制造:工业云渲染的价值闭环

在智能制造、建筑工程、能源电力、船舶海工等工业场景中&#xff0c;3D可视化已从传统的桌面端逐步向Web端迁移&#xff0c;Web 3D凭借其跨平台、轻量化、实时交互等特性&#xff0c;已成为企业构建数字孪生、实现远程协作、推动云端交付的重要工具。这场技术变革不仅改变了工业…

算法第五十一天:图论part02(第十一章)

1.岛屿数量 99. 岛屿数量 &#x1f31f; 思路总结 — DFS 版 1️⃣ 问题本质 给定一个二维矩阵 grid&#xff0c;1 表示陆地&#xff0c;0 表示水 统计岛屿数量&#xff0c;每个岛屿由上下左右相邻的陆地组成 本质是 在二维网格中找连通块 的问题。 2️⃣ 核心思路 遍历矩阵…

杰里708n tws api 简介

/** 通过搜索码搜索tws设备*/int tws_api_search_sibling_by_code();/**打开可发现, 可连接&#xff0c;可被手机和tws搜索到*/int tws_api_wait_pair_by_code(u16 code, const char *name, int timeout_ms);int tws_api_wait_pair_by_ble(u16 code, const char *name, int tim…

高调光比 LED 恒流驱动芯片方案详解AP5165B:36V/1A

AP5165B 是深圳市世微半导体有限公司推出的一款高性能、连续电流模式的降压型&#xff08;Buck&#xff09;LED 恒流驱动芯片。该芯片适用于输入电压高于 LED 电压的应用场景&#xff0c;可驱动单颗或多颗串联的 LED&#xff0c;输出电流最高可达 1A&#xff0c;广泛用于非隔离…

【从零构建企业级线程池管理系统:Python并发编程实战指南】

从零构建企业级线程池管理系统&#xff1a;Python并发编程实战指南 技术博客 | 深入探索Python并发编程、Web开发与现代软件架构设计的完整实践 &#x1f680; 项目背景 在当今高并发的互联网时代&#xff0c;线程池作为并发编程的核心组件&#xff0c;其管理和监控能力直接影…

飞牛系统总是死机,安装个工具查看一下日志

崩溃转储 (kernel crash dump)如果你怀疑是内核 panic&#xff0c;可以开启 kdump 或 kernel crash dump。 安装&#xff1a;sudo apt install kdump-tools # Debian/Ubuntu sudo systemctl enable kdump 下次死机时&#xff0c;系统会把内存 dump 到 /var/crash 里。sudo syst…

2025年AI Agent技术深度解析:原理、应用与未来趋势

一、引言随着人工智能技术的飞速发展&#xff0c;AI Agent&#xff08;智能体&#xff09;作为人工智能领域的重要分支&#xff0c;正逐渐成为推动各行业智能化转型的关键力量。AI Agent具备自主感知、决策和执行能力&#xff0c;能够在复杂环境中完成特定任务&#xff0c;为人…

linux内核 - 内存分配机制介绍

在linux内核中&#xff0c;下面这张图说明了系统中存在一个可以满足各种内存请求的分配机制。根据你需要内存的用途&#xff0c;你可以选择最接近你目标的分配方式。最底层、最基础的分配器是 页分配器&#xff08;page allocator&#xff09;&#xff0c;它以页为单位分配内存…

PyTorch生成式人工智能——ACGAN详解与实现

PyTorch生成式人工智能——ACGAN详解与实现0. 前言1. ACGAN 简介1.1 ACGAN 技术原理1.2 ACGAN 核心思想1.3 损失函数2. 模型训练流程3. 使用 PyTorch 构建 ACGAN3.1 数据处理3.2 模型构建3.3 模型训练3.4 模型测试相关链接0. 前言 在生成对抗网络 (Generative Adversarial Net…

Python + 淘宝 API 开发:自动化采集商品数据的完整流程​

在电商数据分析、竞品监控和市场调研等场景中&#xff0c;高效采集淘宝商品数据是关键环节。本文将详细介绍如何利用 Python 结合 API&#xff0c;构建一套自动化的商品数据采集系统&#xff0c;涵盖从 API 申请到数据存储的完整流程&#xff0c;并提供可直接运行的代码实现。​…

2025.8.21总结

工作一年多了&#xff0c;在这期间&#xff0c;确实也有不少压力&#xff0c;但每当工作有压力的时候&#xff0c;最后面都会解决。好像每次遇到解决不了的事情&#xff0c;都有同事给我兜底。这种压力&#xff0c;确实会加速一个人的成长。这种狼性文化&#xff0c;这种环境&a…

VS2022 - C#程序简单打包操作

文章目录VS2022 - C#程序简单打包操作概述笔记实验过程新建工程让依赖的运行时程序安装包在安装时运行(如果发现运行时不能每次都安装程序&#xff0c;就不要做这步)关于”运行时安装程序无法每次都安装成功“的应对知识点尝试打包旧工程bug修复从需求属性中&#xff0c;可以原…

在JAVA中如何给Main方法传参?

一、在IDEA中进行传参&#xff1a;先创建一个类&#xff1a;MainTestimport java.util.Arrays;public class MainTest {public static void main(String[] args) {System.out.println(args.length);System.out.println(Arrays.toString(args));} }1.IDEA ---> 在运行的按钮上…

ORACLE中如何批量重置序列

背景&#xff1a;数据库所有序列都重置为1了&#xff0c;所以要将所有的序列都更新为对应的表主键&#xff08;这里是id&#xff09;的最大值1。我这里序列的规则是SEQ_表名。BEGINENHANCED_SYNC_SEQUENCES(WJ_CPP); -- 替换为你的模式名 END; / CREATE OR REPLACE PROCEDURE E…

公号文章排版教程:图文双排、添加图片超链接、往期推荐、推文采集(2025-08-21)

文章目录 排版的基本原则 I 图片超链接 方式1: 利用公号原生编辑器 方式2:在CSDN平台使用markdown编辑器, 利用标签实现图片链接。 II 排版小技巧 自定义页面模版教程 使用壹伴进行文章素材的采集 美编助手的往期推荐还不错 利用365编辑器创建图文双排效果 排版的基本原则 亲…

计算两幅图像在特定交点位置的置信度评分。置信度评分反映了该位置特征匹配的可靠性,通常用于图像处理任务(如特征匹配、立体视觉等)

这段代码定义了一个名为compute_confidence的函数&#xff0c;用于计算两幅图像在特定交点位置的置信度评分。置信度评分反映了该位置特征匹配的可靠性&#xff0c;通常用于图像处理任务&#xff08;如特征匹配、立体视觉等&#xff09;。以下是逐部分解析&#xff1a; 3. 结果…

计算机视觉第一课opencv(三)保姆级教学

简介 计算机视觉第一课opencv&#xff08;一&#xff09;保姆级教学 计算机视觉第一课opencv&#xff08;二&#xff09;保姆级教学 今天继续学习opencv。 一、 图像形态学 什么是形态学&#xff1a;图像形态学是一种处理图像形状特征的图像处理技术&#xff0c;主要用于描…

24.早期目标检测

早期目标检测 第一步&#xff0c;计算机图形学做初步大量候选框&#xff0c;把物体圈出来 第二步&#xff0c;依次将所有的候选框图片&#xff0c;输入到分类模型进行判断 选择性搜索 选择搜索算法&#xff08;Selective Search&#xff09;&#xff0c;是一种熟知的计算机图像…

Java基础知识点汇总(三)

一、面向对象的特征有哪些方面 Java中面向对象的特征主要包括以下四个核心方面&#xff1a;封装&#xff08;Encapsulation&#xff09; 封装是指将对象的属性&#xff08;数据&#xff09;和方法&#xff08;操作&#xff09;捆绑在一起&#xff0c;隐藏对象的内部实现细节&am…

GEO优化专家孟庆涛:让AI“聪明”选择,为企业“精准”生长

在生成式AI席卷全球的今天&#xff0c;企业最常遇到的困惑或许是&#xff1a;“为什么我的AI生成内容总像‘模板套娃’&#xff1f;”“用户明明想要A&#xff0c;AI却拼命输出B&#xff1f;”当生成式AI从“能用”迈向“好用”的关键阶段&#xff0c;如何让AI真正理解用户需求…