当前位置: 首页 > article >正文

【C++】B2124 判断字符串是否为回文


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
    • 输入格式:
    • 输出格式:
    • 样例:
  • 💯方法一:我的第一种做法
    • 思路
    • 代码实现
    • 解析
  • 💯方法二:我的第二种做法
    • 思路
    • 代码实现
    • 解析
    • 改进建议
  • 💯方法三:老师的第一种做法
    • 思路
    • 代码实现
    • 解析
    • 优点
  • 💯方法四:老师的第二种做法
    • 思路
    • 代码实现
    • 解析
    • 优点
    • 缺点
  • 💯对比分析
  • 💯扩展:空间优化和实际应用
  • 💯小结


在这里插入图片描述


💯前言

  • 判断一个字符串是否为回文是编程中常见的问题。回文字符串是指从前往后读与从后往前读都一样的字符串。例如,“abcdedcba” 就是回文,而 “abcde” 则不是。对于这类问题,我们可以采用多种不同的算法来解决。在本篇文章中,我们将分析四种不同的做法,并进行对比与优化,以帮助大家更好地理解如何判断字符串是否为回文。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2124 判断字符串是否为回文
在这里插入图片描述

输入一个字符串,判断该字符串是否是回文。回文是指顺读和倒读都一样的字符串。

输入格式:

输入一行字符串,长度小于100。

输出格式:

如果字符串是回文,输出 yes;否则,输出 no

样例:

输入

abcdedcba

输出

yes

💯方法一:我的第一种做法

思路

我的第一种做法是通过反转字符串来判断回文。首先,我们将原字符串反转,然后与原字符串进行比较。如果反转后的字符串与原字符串相等,则说明原字符串是回文。

代码实现

#include <iostream>
#include <string>
using namespace std;int main() {string s;cin >> s;  // 输入字符串int left = 0;int right = s.size() - 1;// 检查字符串的前半部分是否与后半部分对称while (left < right) {if (s[left] != s[right]) {cout << "no" << endl;  // 如果有不同字符,输出noreturn 0;}left++;right--;}cout << "yes" << endl;  // 如果没有不同字符,输出yesreturn 0;
}

解析

  1. 反转字符串:通过双指针方式,使用 leftright 两个指针分别从字符串的两端开始向中间移动,逐个比较字符。
  2. 时间复杂度:O(n),其中 n 是字符串的长度。我们最多需要遍历字符串的前半部分,进行字符比较。
  3. 空间复杂度:O(1),仅使用了常数的空间来存储指针 leftright

💯方法二:我的第二种做法

思路

在我的第二种做法中,我尝试使用了两次循环,首先将字符串反转到一个新的字符串 s2 中,然后通过逐字符对比 s2 和原字符串 s1 是否一致来判断回文。

代码实现

#include <iostream>
#include <string>
using namespace std;int main() {string s1, s2;while(cin >> s1) {s2.resize(s1.size());  for(int i = s1.size() - 1; i >= 0; i--) {s2[s1.size() - i - 1] = s1[i];}int temp = 1;for(int i = 0; i < s1.size(); i++) {if(s2[i] != s1[i]) {temp = 0;break;}}if(temp)cout << "yes" << endl;elsecout << "no" << endl;}return 0;
}

解析

  1. 字符串反转:首先创建一个 s2 字符串,并使用 for 循环反转 s1 字符串的内容,存储到 s2 中。
  2. 回文判断:然后通过逐个字符对比 s2s1,如果遇到不同的字符,则输出 no
  3. 存在问题
    • s2 没有预先调整大小s2 在反转前没有设置大小,可能会导致内存越界。可以通过 resize 来调整其大小。
    • 逻辑错误break 的位置存在问题,导致判断逻辑不正确,跳出循环时判断不够精确。

改进建议

通过双指针法可以优化空间使用,并且避免了额外的字符串存储开销。具体改进后我们会在后面介绍。

💯方法三:老师的第一种做法

思路

老师的第一种做法采用了双指针法。这是一种非常高效的方法。通过两个指针,分别从字符串的两端开始,逐个比较字符,如果出现不同的字符,就可以直接返回 no,否则直到两个指针相遇时,输出 yes

代码实现

#include <iostream>
#include <string>
using namespace std;int main() {string s;cin >> s;  // 输入字符串int left = 0;int right = s.size() - 1;while (left < right) {if (s[left] != s[right]) {cout << "no" << endl;  // 如果有不同字符,输出noreturn 0;}left++;right--;}cout << "yes" << endl;  // 如果没有不同字符,输出yesreturn 0;
}

解析

  1. 双指针法:通过两个指针 leftright 从字符串的两端向中间逼近。每次比较 s[left]s[right],如果发现不相等,直接返回 no,否则继续向中间推进。
  2. 时间复杂度:O(n),每次最多需要遍历一次字符串的长度。
  3. 空间复杂度:O(1),只使用了常数空间来存储两个指针。

优点

  1. 空间复杂度为 O(1),避免了额外的空间开销。
  2. 效率高,每次只进行一次字符比较,比反转字符串的方法更直接且高效。

💯方法四:老师的第二种做法

思路

老师的第二种做法使用了标准库中的 reverse 函数,将字符串反转后直接与原字符串进行比较。这是一种简洁的做法,但其空间复杂度稍高,因为需要额外的存储空间来保存反转后的字符串。

代码实现

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;int main() {string s;cin >> s;string t = s;reverse(t.begin(), t.end());  // 反转字符串if (t == s) cout << "yes" << endl;elsecout << "no" << endl;return 0;
}

解析

  1. 字符串反转:利用 reverse 函数将字符串 s 反转,并保存到 t 中。
  2. 回文判断:通过直接比较反转后的字符串 t 和原字符串 s 是否相等来判断回文。

优点

  1. 代码简洁:通过标准库函数,代码更加简洁和易懂。
  2. 实现简单:使用 reverse 可以减少手动反转字符串的工作量。

缺点

  1. 空间复杂度为 O(n),因为需要额外的字符串 t 来存储反转后的字符串。

💯对比分析

  1. 空间复杂度

    • 我的第一种做法和老师的第一种做法都使用了 O(1) 空间,通过双指针来直接判断回文。
    • 我的第二种做法和老师的第二种做法需要额外的 O(n) 空间来存储反转后的字符串。
  2. 时间复杂度

    • 所有方法的时间复杂度均为 O(n),其中 n 是字符串的长度。
  3. 可读性与简洁性

    • 我的第二种做法和老师的第二种做法通过反转字符串,代码简单易懂。
    • 我的第一种做法和老师的第一种做法更加高效,避免了不必要的空间开销。

💯扩展:空间优化和实际应用

在一些实际应用中,空间的使用往往是一个重要的考虑因素。如果我们能够通过优化算法减少空间复杂度,将会使得程序更高效。双指针法就是在空间优化方面的一个典型例子,它避免了反转字符串时的额外存储。

💯小结

本文通过分析四种不同的做法来判断字符串是否为回文,比较了它们在空间和时间复杂度上的表现。通过这几种做法,我们可以发现,双指针法在空间和时间上的优势较为明显,是最为推荐的解决方案。当然,对于小规模的问题,使用字符串反转的做法也不失为一种简洁高效的选择。

希望本篇文章能够帮助大家更好地理解字符串回文判断的不同做法,并能够根据实际问题选择合适的算法。


在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

相关文章:

【C++】B2124 判断字符串是否为回文

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式&#xff1a;输出格式&#xff1a;样例&#xff1a; &#x1f4af;方法一&#xff1a;我的第一种做法思路代码实现解析 &#x1f4af;方法二&#xff1a;我…...

DeepSpeed Zero 解读

目录 主要参考: 分布式训练基础 – 数据并行&#xff0c;模型并行&#xff0c;流水线并行 DeepSpeed Zero 的各个 stage 介绍 针对Zero 的各个stage&#xff0c;这里有三个点需要额外再说一下&#xff1a; 各个stage&#xff0c;要实现将某一部分参数分配到不同GPU&#xff0c…...

Windows 安装Linux子系统

文章目录 一、启用虚拟化二、安装子系统1. 查看所有官方支持的 WSL 发行版2. 安装 Ubuntu3. 安装非官方发行版(如 CentOS)三、启动和更新子系统1. 启动Ubuntu终端2. 更新系统四、管理已安装的发行版在 Windows 的 WSL(Windows Subsystem for Linux)中,除了 Ubuntu,你还可…...

基于Spring Security 6的OAuth2 系列之八 - 授权服务器--Spring Authrization Server的基本原理

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…...

【LeetCode 刷题】回溯算法(5)-棋盘问题

此博客为《代码随想录》二叉树章节的学习笔记&#xff0c;主要内容为回溯算法棋盘问题相关的题目解析。 文章目录 51. N皇后37. 解数独332.重新安排行程 51. N皇后 题目链接 class Solution:def solveNQueens(self, n: int) -> List[List[str]]:board [[. for _ in rang…...

PaddleOCR 截图自动文字识别

春节假期在家无聊&#xff0c;撸了三个小工具&#xff1a;PC截图编辑/PC录屏(用于meeting录屏)/PC截屏文字识别。因为感觉这三个小工具是工作中常常需要用到的&#xff0c;github上也有很多开源的&#xff0c;不过总有点或多或少的小问题&#xff0c;不利于自己的使用。脚本的编…...

算法题(48):反转链表

审题&#xff1a; 需要我们将链表反转并返回头结点地址 思路&#xff1a; 一般在面试中&#xff0c;涉及链表的题会主要考察链表的指向改变&#xff0c;所以一般不会允许我们改变节点val值。 这里是单向链表&#xff0c;如果要把指向反过来则需要同时知道前中后三个节点&#x…...

梯度、梯度下降、最小二乘法

在求解机器学习算法的模型参数&#xff0c;即无约束优化问题时&#xff0c;梯度下降是最常采用的方法之一&#xff0c;另一种常用的方法是最小二乘法。 1. 梯度和梯度下降 在微积分里面&#xff0c;对多元函数的参数求∂偏导数&#xff0c;把求得的各个参数的偏导数以向量的形式…...

独立开发者小程序开发变现思路

随着移动互联网的发展&#xff0c;小程序已成为许多独立开发者展示才能和实现收入的重要平台。作为一种轻量级的应用形态&#xff0c;小程序具有开发成本低、用户体验好、传播效率高等优势&#xff0c;为独立开发者提供了多种变现方式。然而&#xff0c;要想实现真正的盈利&…...

软件测试 - 概念篇

目录 1. 需求 1.1 用户需求 1.2 软件需求 2. 开发模型 2.1 软件的生命周期 2.2 常见开发模型 2.2.1 瀑布模型 2.2.2 螺旋模型 1. 需求 对于软件开发而言, 需求分为以下两种: 用户需求软件需求 1.1 用户需求 用户需求, 就是用户提出的需求, 没有经过合理的评估, 通常…...

使用SpringBoot发送邮件|解决了部署时连接超时的bug|网易163|2025

使用SpringBoot发送邮件 文章目录 使用SpringBoot发送邮件1. 获取网易邮箱服务的授权码2. 初始化项目maven部分web部分 3. 发送邮件填写配置EmailSendService [已解决]部署时连接超时附&#xff1a;Docker脚本Dockerfile创建镜像启动容器 1. 获取网易邮箱服务的授权码 温馨提示…...

基于springboot+vue的航空散货调度系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

自学习记录-编程语言的特点(持续记录)

我学习的顺序是C -> python -> C -> Java。在讲到某项语言的特点是&#xff0c;可能会时不时穿插其他语言的特点。 Java 1 注解Annotation Python中也有类似的Decorators。以下为AI学习了解到的&#xff1a; Java的Annotation是一种元数据&#xff08;metadata)&a…...

[MRCTF2020]Ez_bypass1(md5绕过)

[MRCTF2020]Ez_bypass1(md5绕过) ​​ 这道题就是要绕过md5强类型比较&#xff0c;但是本身又不相等&#xff1a; md5无法处理数组&#xff0c;如果传入的是数组进行md5加密&#xff0c;会直接放回NULL&#xff0c;两个NuLL相比较会等于true&#xff1b; 所以?id[]1&gg…...

MATLAB实现多种群遗传算法

多种群遗传算法&#xff08;MPGA, Multi-Population Genetic Algorithm&#xff09;是一种改进的遗传算法&#xff0c;它通过将种群分成多个子种群并在不同的子种群之间进行交叉和交换&#xff0c;旨在提高全局搜索能力并避免早期收敛。下面是多种群遗传算法的主要步骤和流程&a…...

强化学习笔记(5)——PPO

PPO视频课程来源 首先理解采样期望的转换 变量x在p(x)分布下&#xff0c;函数f(x)的期望 等于f(x)乘以对应出现概率p(x)的累加 经过转换后变成 x在q(x)分布下&#xff0c;f(x)*p(x)/q(x) 的期望。 起因是&#xff1a;求最大化回报的期望&#xff0c;所以对ceta求梯度 具体举例…...

【MATLAB例程】TOA和AOA混合的高精度定位程序,适用于三维、N锚点的情况

代码实现了一个基于到达角&#xff08;AOA&#xff09;和到达时间&#xff08;TOA&#xff09;混合定位的例程。该算法能够根据不同基站接收到的信号信息&#xff0c;自适应地计算目标的位置&#xff0c;适用于多个基站的场景 文章目录 主要功能代码结构运行结果程序代码 主要功…...

使用Pygame制作“青蛙过河”游戏

本篇博客将演示如何使用 Python Pygame 从零开始编写一款 Frogger 风格的小游戏。Frogger 是一款早期街机经典&#xff0c;玩家需要帮助青蛙穿越车水马龙的马路到达对岸。本示例提供了一个精简原型&#xff0c;包含角色移动、汽车生成与移动、碰撞检测、胜利条件等关键点。希望…...

深度解读 Docker Swarm

一、引言 随着业务规模的不断扩大和应用复杂度的增加,容器集群管理的需求应运而生。如何有效地管理和调度大量的容器,确保应用的高可用性、弹性伸缩和资源的合理分配,成为了亟待解决的问题。Docker Swarm 作为 Docker 官方推出的容器集群管理工具,正是在这样的背景下崭露头…...

8、面向对象:类、封装、构造方法

一、类 1、定义 类&#xff1a;对现实世界中事物的抽象。Student 对象&#xff1a;现实世界中具体的个体。张三、李四 这些具体的学生 面向对象的特征&#xff1a;抽象、封装、继承、多态 OOP: Object Oriented Programming&#xff08;面向对象编程&#xff09; 类和对象…...

AI时代IT行业职业方向规划大纲

一、引言 AI时代的颠覆性影响 ChatGPT、Midjourney等生成式AI对传统工作模式的冲击 案例&#xff1a;AI编程助手&#xff08;GitHub Copilot&#xff09;改变开发者工作流程 核心问题&#xff1a;IT从业者如何避免被AI替代&#xff0c;并找到新机遇&#xff1f; 二、AI时代…...

STM32 旋转编码器

旋转编码器简介 旋转编码器&#xff1a;用来测量位置、速度或旋转方向的装置&#xff0c;当其旋转轴旋转时&#xff0c;其输出端可以输出与旋转速度和方向对应的方波信号&#xff0c;读取方波信号的频率和相位信息即可得知旋转轴的速度和方向 类型&#xff1a;机械触点式/霍尔传…...

大模型领域的Scaling Law的含义及作用

Scaling Law就像是一个“长大公式”&#xff0c;用来预测当一个东西&#xff08;比如模型&#xff09;变大&#xff08;比如增加参数、数据量&#xff09;时&#xff0c;它的性能&#xff08;比如准确率&#xff09;会怎么变化。 它能帮助我们提前知道&#xff0c;增加多少资源…...

从 C 到 C++:理解结构体中字符串的存储与操作

对于刚入门 C/C 的程序员来说&#xff0c;字符串的存储和操作可能是个容易混淆的知识点。在 C 中&#xff0c;std::string 提供了非常友好的接口&#xff0c;我们可以轻松地在结构体中使用字符串类型&#xff0c;无需关注底层细节。然而&#xff0c;在 C 语言中&#xff0c;字符…...

git基础使用--4---git分支和使用

文章目录 git基础使用--4---git分支和使用1. 按顺序看2. 什么是分支3. 分支的基本操作4. 分支的基本操作4.1 查看分支4.2 创建分支4.3 切换分支4.4 合并冲突 git基础使用–4—git分支和使用 1. 按顺序看 -git基础使用–1–版本控制的基本概念 -git基础使用–2–gti的基本概念…...

【算法】回溯算法专题③ ——排列型回溯 python

目录 前置小试牛刀回归经典举一反三总结 前置 【算法】回溯算法专题① ——子集型回溯 python 【算法】回溯算法专题② ——组合型回溯 剪枝 python 小试牛刀 全排列 https://leetcode.cn/problems/permutations/description/ 给定一个不含重复数字的数组 nums &#xff0c;返…...

Vue2.x简介

Vue2.x简介 Vue2.x的版本介绍Vue2.x的两大组件库 Vue2.x的版本介绍 Vue2.x是vue.js的第二个主要版本&#xff0c;最初版发布于2016 年&#xff0c;最终版发布于2023年12月24日&#xff08;版本号&#xff1a;2.7.16&#xff0c;版本名&#xff1a;Swan Song&#xff08;绝唱&a…...

FFmpeg:多媒体处理的瑞士军刀

FFmpeg&#xff1a;多媒体处理的瑞士军刀 前言 FFmpeg 是一个功能强大且跨平台的开源多媒体框架&#xff0c;广泛应用于音视频处理领域。 它由多个库和工具组成&#xff0c;能够处理各种音视频格式&#xff0c;涵盖编码、解码、转码、流处理等多种操作。 无论是专业视频编辑…...

Windows编译FreeRDP步骤

1. **安装必要工具** powershell # 安装 Visual Studio 2022 (勾选"C桌面开发"组件) # 安装 CMake: https://cmake.org/download/ # 安装 Git: https://git-scm.com/ 2. **安装依赖项** powershell # 使用vcpkg包管理 git clone https://github.com/Microsoft/vcpk…...

机器学习--学习计划

3周机器学习速成计划 基于「28原则」&#xff0c;聚焦机器学习20%的核心概念&#xff0c;覆盖80%的常见应用场景。计划分为 理论学习 项目实战&#xff0c;每周学习后通过5个递进项目巩固知识。 &#x1f4c5; 第1周&#xff1a;数据与监督学习基础 学习目标&#xff1a;掌握…...