【2024年华为OD机试】(A卷,100分)- 单词倒序(Java JS PythonC/C++)

在这里插入图片描述

一、问题描述

题目描述

输入单行英文句子,里面包含英文字母,空格以及,.?三种标点符号,请将句子内每个单词进行倒序,并输出倒序后的语句。

输入描述

输入字符串S,S的长度 1 ≤ N ≤ 100

输出描述

输出倒序后的字符串

备注

标点符号左右的空格 ≥ 0,单词间空格>0

用例

输入

yM eman si boB.

输出

My name is Bob.

说明

输入

woh era uoy ? I ma enif.

输出

how are you ? I am fine.

说明

题目解析

从用例可以看出,单词的倒序并不难,将字符串单词转为字符数组后,reverse一下就行了。但是单词中如果有标点符号的话,则标点符号的位置不能改变,比如enif. 倒序后为 fine. 其中 . 的位置在倒序前后是一样的。

我的解题思路

从左到右遍历每一个字符,如果字符是 , . ? 或者空格,则看成一个分界符,将分界符之间的单词片段进行倒序。

二、JavaScript算法源码

以下是基于 JavaScript 的代码的中文详细注释和逻辑讲解:


代码逻辑

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");// 创建 readline 接口,用于从控制台读取输入
const rl = readline.createInterface({input: process.stdin,  // 输入流output: process.stdout, // 输出流
});// 监听输入事件,每次输入一行时触发
rl.on("line", (line) => {// 调用 getResult 函数处理输入,并输出结果console.log(getResult(line));
});// 处理输入字符串的函数
function getResult(str) {// 定义正则表达式,匹配逗号、句号、问号和空格const reg = /[\,\.\?\s]/;// 定义数组 idxs,用于存储分隔符的位置// 初始值为 -1,表示字符串的起始位置const idxs = [-1];// 遍历输入字符串,找到所有分隔符的位置for (let i = 0; i < str.length; i++) {if (reg.test(str[i])) {idxs.push(i); // 将分隔符的位置存入 idxs}}// 将字符串的结束位置(str.length)加入 idxsidxs.push(str.length);// 将字符串转换为数组,方便修改const arr = [...str];// 使用 reduce 方法遍历 idxs 数组// 对每个分隔符之间的子串进行反转idxs.reduce((p, c) => {// p 是前一个分隔符的位置,c 是当前分隔符的位置let l = p + 1; // 子串的起始位置let r = c - 1; // 子串的结束位置// 反转子串while (l < r) {let tmp = arr[l];arr[l] = arr[r];arr[r] = tmp;l++;r--;}// 返回当前分隔符的位置,作为下一次 reduce 的 preturn c;});// 将数组重新拼接为字符串并返回return arr.join("");
}

代码讲解

  1. 输入处理

    • 使用 readline 模块从控制台读取输入。
    • 每次输入一行时,触发 line 事件,调用 getResult 函数处理输入。
  2. 分隔符匹配

    • 定义正则表达式 reg,用于匹配逗号、句号、问号和空格。
    • 遍历输入字符串,找到所有分隔符的位置,并存入数组 idxs
  3. 字符串反转

    • 将输入字符串转换为数组 arr,方便修改。
    • 使用 reduce 方法遍历 idxs 数组,对每个分隔符之间的子串进行反转。
    • 反转逻辑:
      • 定义子串的起始位置 l 和结束位置 r
      • 使用双指针法交换字符,直到 lr 相遇。
  4. 结果输出

    • 将反转后的数组 arr 重新拼接为字符串并返回。

示例解析

输入
Hello, world! This is a test.
运行结果
olleH, dlrow! sihT si a tset.
  • 解析:
    • 分隔符包括逗号、空格和句号。
    • 反转每个分隔符之间的子串:
      • HelloolleH
      • worlddlrow
      • ThissihT
      • issi
      • aa
      • testtset

总结

  • 该代码通过正则表达式匹配分隔符,并使用双指针法反转每个分隔符之间的子串。
  • 适用于需要对字符串中特定分隔符之间的子串进行反转的场景。
  • 代码逻辑清晰,注释详细,便于理解和扩展。

更精简的解法,可以利用String.prototype.repalce的正则匹配出输入字符串中各个英文子串,将这些英文子串替换为倒序子串,关于repalce的正则匹配用法请看:

String.prototype.repalce的正则匹配

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});rl.on("line", (line) => {console.log(getResult(line));
});function getResult(str) {return str.replace(/[a-zA-Z]+/g, (s) => [...s].reverse().join(""));
}

如果有其他问题,欢迎随时提问!

三、Java算法源码

以下是基于 Java 的代码的中文详细注释和逻辑讲解:


代码逻辑

import java.util.ArrayList;
import java.util.Scanner;public class Main {public static void main(String[] args) {// 创建 Scanner 对象,用于从控制台读取输入Scanner sc = new Scanner(System.in);// 读取一行输入String str = sc.nextLine();// 调用 getResult 方法处理输入,并输出结果System.out.println(getResult(str));}// 处理输入字符串的方法public static String getResult(String str) {// 定义 ArrayList,用于存储分隔符的位置ArrayList<Integer> idxs = new ArrayList<>();// 初始值为 -1,表示字符串的起始位置idxs.add(-1);// 遍历输入字符串,找到所有分隔符的位置for (int i = 0; i < str.length(); i++) {// 判断当前字符是否为分隔符(逗号、句号、问号或空格)if (",.? ".indexOf(str.charAt(i)) != -1) {idxs.add(i); // 将分隔符的位置存入 idxs}}// 将字符串的结束位置(str.length())加入 idxsidxs.add(str.length());// 将字符串转换为字符数组,方便修改char[] chars = str.toCharArray();// 遍历 idxs 数组,对每个分隔符之间的子串进行反转for (int i = 0; i < idxs.size() - 1; i++) {// 获取当前分隔符之间的子串的起始位置和结束位置int l = idxs.get(i) + 1; // 子串的起始位置int r = idxs.get(i + 1) - 1; // 子串的结束位置// 使用双指针法反转子串while (l < r) {char tmp = chars[l];chars[l] = chars[r];chars[r] = tmp;l++;r--;}}// 将字符数组重新拼接为字符串StringBuilder sb = new StringBuilder();for (char c : chars) {sb.append(c);}// 返回结果字符串return sb.toString();}
}

代码讲解

  1. 输入处理

    • 使用 Scanner 从控制台读取一行输入。
    • 调用 getResult 方法处理输入字符串。
  2. 分隔符匹配

    • 定义 ArrayList<Integer> 存储分隔符的位置。
    • 初始值为 -1,表示字符串的起始位置。
    • 遍历输入字符串,找到所有分隔符(逗号、句号、问号或空格)的位置,并存入 idxs
  3. 字符串反转

    • 将输入字符串转换为字符数组 chars,方便修改。
    • 遍历 idxs 数组,对每个分隔符之间的子串进行反转。
    • 反转逻辑:
      • 定义子串的起始位置 l 和结束位置 r
      • 使用双指针法交换字符,直到 lr 相遇。
  4. 结果输出

    • 使用 StringBuilder 将字符数组重新拼接为字符串。
    • 返回结果字符串。

示例解析

输入
Hello, world! This is a test.
运行结果
olleH, dlrow! sihT si a tset.
  • 解析:
    • 分隔符包括逗号、空格和句号。
    • 反转每个分隔符之间的子串:
      • HelloolleH
      • worlddlrow
      • ThissihT
      • issi
      • aa
      • testtset

总结

  • 该代码通过遍历字符串找到分隔符的位置,并使用双指针法反转每个分隔符之间的子串。
  • 适用于需要对字符串中特定分隔符之间的子串进行反转的场景。
  • 代码逻辑清晰,注释详细,便于理解和扩展。

如果有其他问题,欢迎随时提问!

四、Python算法源码

以下是基于 Python 的代码的中文详细注释和逻辑讲解:


代码逻辑

原始代码
import re# 从控制台读取输入
s = input()# 定义正则表达式,匹配逗号、句号、问号和空格
p = re.compile(r"[\\,\\.\\?\s]")# 定义数组 idxs,用于存储分隔符的位置
# 初始值为 -1,表示字符串的起始位置
idxs = [-1]# 遍历输入字符串,找到所有分隔符的位置
for i in range(len(s)):if p.match(s[i]):idxs.append(i)# 将字符串的结束位置(len(s))加入 idxs
idxs.append(len(s))# 将字符串转换为列表,方便修改
arr = [c for c in s]# 遍历 idxs 数组,对每个分隔符之间的子串进行反转
for i in range(len(idxs) - 1):l = idxs[i] + 1  # 子串的起始位置r = idxs[i + 1] - 1  # 子串的结束位置# 使用双指针法反转子串while l < r:arr[l], arr[r] = arr[r], arr[l]l += 1r -= 1# 将列表重新拼接为字符串并输出
print("".join(arr))
优化后的代码
import re# 从控制台读取输入
s = input()# 定义替换函数 rep,用于反转匹配的子串
def rep(matched):# 将匹配的子串转换为列表并反转tmp = list(matched.group())tmp.reverse()# 将反转后的列表重新拼接为字符串并返回return "".join(tmp)# 使用 re.sub 方法,将匹配的子串替换为反转后的结果
# 正则表达式 r"[a-zA-Z]+" 匹配一个或多个字母
print(re.sub(r"[a-zA-Z]+", rep, s))

代码讲解

原始代码
  1. 输入处理

    • 使用 input() 从控制台读取输入字符串。
  2. 分隔符匹配

    • 定义正则表达式 p,用于匹配逗号、句号、问号和空格。
    • 遍历输入字符串,找到所有分隔符的位置,并存入数组 idxs
  3. 字符串反转

    • 将输入字符串转换为列表 arr,方便修改。
    • 遍历 idxs 数组,对每个分隔符之间的子串进行反转。
    • 反转逻辑:
      • 定义子串的起始位置 l 和结束位置 r
      • 使用双指针法交换字符,直到 lr 相遇。
  4. 结果输出

    • 将反转后的列表 arr 重新拼接为字符串并输出。
优化后的代码
  1. 输入处理

    • 使用 input() 从控制台读取输入字符串。
  2. 替换函数

    • 定义函数 rep,用于处理正则匹配的结果。
    • 将匹配的子串转换为列表并反转,然后重新拼接为字符串。
  3. 正则替换

    • 使用 re.sub 方法,将匹配的子串替换为反转后的结果。
    • 正则表达式 r"[a-zA-Z]+" 匹配一个或多个字母。
  4. 结果输出

    • 直接输出替换后的字符串。

示例解析

输入
Hello, world! This is a test.
原始代码运行结果
olleH, dlrow! sihT si a tset.
  • 解析:
    • 分隔符包括逗号、空格和句号。
    • 反转每个分隔符之间的子串:
      • HelloolleH
      • worlddlrow
      • ThissihT
      • issi
      • aa
      • testtset
优化后代码运行结果
olleH, dlrow! sihT si a tset.
  • 解析:
    • 正则表达式 r"[a-zA-Z]+" 匹配所有字母子串。
    • 对每个匹配的子串进行反转:
      • HelloolleH
      • worlddlrow
      • ThissihT
      • issi
      • aa
      • testtset

总结

  • 原始代码通过遍历字符串找到分隔符的位置,并使用双指针法反转每个分隔符之间的子串。
  • 优化后的代码利用 re.sub 方法和正则表达式,直接匹配字母子串并反转,代码更简洁高效。
  • 两种方法均适用于需要对字符串中特定子串进行反转的场景。

如果有其他问题,欢迎随时提问!

五、C/C++算法源码:

以下是基于 C++ 的代码实现,并附上中文详细注释和逻辑讲解:


C++ 代码实现

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <regex>using namespace std;// 定义替换函数 rep,用于反转匹配的子串
string rep(const smatch& matched) {string tmp = matched.str(); // 获取匹配的子串reverse(tmp.begin(), tmp.end()); // 反转子串return tmp; // 返回反转后的子串
}int main() {// 从控制台读取输入string s;getline(cin, s);// 定义正则表达式,匹配一个或多个字母regex pattern("[a-zA-Z]+");// 使用 regex_replace 方法,将匹配的子串替换为反转后的结果// 第三个参数 rep 是一个函数,用于处理匹配的子串string result = regex_replace(s, pattern, rep);// 输出结果cout << result << endl;return 0;
}

代码讲解

1. 输入处理
  • 使用 getline(cin, s) 从控制台读取一行输入,并存储到字符串 s 中。
2. 正则表达式
  • 定义正则表达式 pattern,用于匹配一个或多个字母([a-zA-Z]+)。
3. 替换函数
  • 定义函数 rep,用于处理正则匹配的结果。
    • 参数 matchedsmatch 类型,表示正则匹配的结果。
    • 使用 matched.str() 获取匹配的子串。
    • 使用 reverse(tmp.begin(), tmp.end()) 反转子串。
    • 返回反转后的子串。
4. 正则替换
  • 使用 regex_replace 方法,将输入字符串 s 中所有匹配的子串替换为反转后的结果。
    • 第一个参数是输入字符串 s
    • 第二个参数是正则表达式 pattern
    • 第三个参数是替换函数 rep
5. 结果输出
  • 输出替换后的字符串 result

示例解析

输入
Hello, world! This is a test.
运行结果
olleH, dlrow! sihT si a tset.
  • 解析:
    • 正则表达式 [a-zA-Z]+ 匹配所有字母子串。
    • 对每个匹配的子串进行反转:
      • HelloolleH
      • worlddlrow
      • ThissihT
      • issi
      • aa
      • testtset

总结

  • 该代码利用 C++ 的正则表达式库 <regex>,实现了对输入字符串中所有字母子串的反转。
  • 通过 regex_replace 方法和自定义替换函数 rep,代码简洁高效。
  • 适用于需要对字符串中特定子串进行反转的场景。

如果有其他问题,欢迎随时提问!

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

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

相关文章

插入实体自增主键太长,mybatis-plaus自增主键

1、问题 spring-boot整合mybtais执行insert语句时&#xff0c;主键id为长文本数据。 2、分析问题 1)数据库主键是否自增 2&#xff09;数据库主键的种子值设置的多少 3、解决问题 1&#xff09;数据库主键设置的时自增 3&#xff09;种子值是1 所以排查是数据库的问题 4、继…

Java高频面试之SE-11

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java中是引用传递还是值传递&#xff1f; 在 Java 中&#xff0c;方法参数传递是通过 值传递 的方式实现的&#xff0c;但这可能会引起一…

Proser:升级为简易的通讯调试助手软件

我本来打算将Proser定位为一个直观的协议编辑、发送端模拟软件&#xff0c;像下面这样。 但是按耐不住升级的心理&#xff0c;硬生生的把即时收发整合了进去&#xff0c;就像这样&#xff01; 不过&#xff0c;目前针对即时收发还没有发送历史、批量发送等功能&#xff0c;…

php 使用simplexml_load_string转换xml数据格式失败

本文介绍如何使用php函数解析xml数据为数组。 <?php$a <xml><ToUserName><![CDATA[ww8b77afac71336111]]></ToUserName><FromUserName><![CDATA[sys]]></FromUserName><CreateTime>1736328669</CreateTime><Ms…

计算机视觉算法实战——打电话行为检测

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​​​ ​​​​​​​​​​​​​​​ ​​​​​​ ​ 1. 引言✨✨ 随着智能手机的普及&#xff0c;打电话行为检测成为了计算机视…

SpringBoot日常:集成Kafka

文章目录 1、pom.xml文件2、application.yml3、生产者配置类4、消费者配置类5、消息订阅6、生产者发送消息7、测试发送消息 本章内容主要介绍如何在springboot项目对kafka进行整合&#xff0c;最终能达到的效果就是能够在项目中通过配置相关的kafka配置&#xff0c;就能进行消息…

HTTPS SSL/TLS 工作流程

目录 一、HTTP/HTTPS 简介1、HTTP协议相关内容2、HTTPS协议3、HTTP版本差异&#xff1a; 二、HTTPS 协议工作流程解析1. 客户端请求 SSL 握手2. 服务端接收 SSL 握手连接3. TLS 握手中的密钥协商4. HTTP 数据的加密与解密5. 安全性保障 三、HTTPS 协议的相关知识拓展1. TLS 与 …

Ubuntu中使用miniconda安装R和R包devtools

安装devtools环境包 sudo apt-get install gfortran -y sudo apt-get install build-essential -y sudo apt-get install libxt-dev -y sudo apt-get install libcurl4-openssl-dev -y sudo apt-get install libxml2.6-dev -y sudo apt-get install libssl-dev -y sudo apt-g…

解决SpringBoot无法使用JDK8问题

解决SpringBoot无法使用JDK8问题 现状解决方案 现状 使用idea创建springboot项目无法选择java8。原因是23年11月的spring更新后就明确了不在支持java8版本的项目创建&#xff0c;但是目前为止很多公司开发还在用java8&#xff0c;导致会有问题的产生。 解决方案 使用idea创…

八、系统托盘与配置面板

没有人会把你变得越来越好&#xff0c;时间和经历只是陪衬。 支撑你变得越来越好的&#xff0c;是你自己坚强的意志、修养、品行、以及不断的反思和经验。 人生最好的贵人&#xff0c;就是努力向上的自己。 一、系统托盘 1、资源文件夹 新建资源文件夹&#xff0c;我们需要把…

IntelliJ IDEA中Maven项目的配置、创建与导入全攻略

大家好&#xff0c;我是袁庭新。 IntelliJ IDEA是当前最流行的Java IDE&#xff08;集成开发环境&#xff09;之一&#xff0c;也是业界公认最好用的Java开发工具之一。IntelliJ IDEA支持Maven的全部功能&#xff0c;通过它我们可以很轻松地实现创建Maven项目、导入Maven项目、…

Element-plus、Element-ui之Tree 树形控件回显Bug问题。

需求&#xff1a;提交时&#xff0c;需要把选中状态和半选中状态 的数据id提交。如图所示&#xff1a; 数据回显时&#xff0c;会出现代码如下&#xff1a; <template><el-tree ref"treeRef" :data"tree" show-checkbox node-key"id" …

C语言#define定义宏

目录 一、什么是宏以及宏的声明方式 1.宏常量&#xff1a; 2.宏函数&#xff1a; 二、宏的替换原则 三、宏设计的易犯错误 ERROR1&#xff1a;尾部加分号&#xff08;当然有些特定需要加了分号&#xff0c;这里说明一般情况&#xff09; ERROR2&#xff1a;宏函数定义时&…

第33 章 - ES 实战篇 - MySQL 与 Elasticsearch 的一致性问题

思维导图 0. 前言 MySQL 与 Elasticsearch 一致性问题是老生常谈了。网上有太多关于这方面的文章了&#xff0c;但是千篇一律&#xff0c;看了跟没看没有太大区别。 在生产中&#xff0c;我们往往会通过 DTS 工具将 binlog 导入到 Kafka&#xff0c;再通过 Kafka 消费 binlog&…

Gitlab-Runner配置

原理 Gitlab-Runner是一个非常强大的CI/CD工具。它可以帮助我们自动化执行各种任务&#xff0c;如构建、测试和部署等。Gitlab-Runner和Gitlab通过API通信&#xff0c;接收作业并提交到执行队列&#xff0c;Gitlab-Runner从队列中获取作业&#xff0c;并允许在不同环境下进行作…

STM32第6章、WWDG

一、简介 WWDG&#xff1a;全称Window watchdog&#xff0c;即窗口看门狗&#xff0c;本质上是一个能产生系统复位信号和提前唤醒中断的计数器。 特性&#xff1a; 是一个递减计数器。 看门狗被激活后&#xff0c; 当递减计数器值从 0x40减到0x3F时会产生复位&#xff08;即T6位…

【Qt】事件、qt文件

目录 Qt事件 QEvent QMouseEvent QWheelEvent QKeyEvent QTimerEvent Qt文件 QFile QFileInfo Qt事件 在Qt中用一个对象表示一个事件&#xff0c;这些事件对象都继承自抽象类QEvent。事件和信号的目的是一样的&#xff0c;都是为了响应用户的操作。有两种产生事件的方…

Jenkins触发器--在其他项目执行后构建

前言&#xff1a; jenkins中有多种触发器可用&#xff0c;可以方便的控制构建的启动 这里简单介绍下项目后构建的配置方法 1. 解释&#xff1a; Build after other projects are built Set up a trigger so that when some other projects finish building, a new build is…

OpenStack 网络服务的插件架构

OpenStack 的网络服务具有灵活的插件架构&#xff0c;可支持多种不同类型的插件以满足不同的网络需求。以下是对 OpenStack 网络服务插件架构中一些常见插件类型的介绍&#xff1a; 一、SDN 插件 Neutron 与 SDN 的集成&#xff1a;在 OpenStack 网络服务里&#xff0c;SDN 插…

牛客网刷题 ——C语言初阶(6指针)——BC105 矩阵相等判定

1. 题目描述&#xff1a;BC105 矩阵相等判定 牛客网OJ题链接 描述&#xff1a; KiKi得到了两个n行m列的矩阵&#xff0c;他想知道两个矩阵是否相等&#xff0c;请你回答他。(当两个矩阵对应数组元素都相等时两个矩阵相等)。 示例1 输入&#xff1a; 2 2 1 2 3 4 1 2 3 4 输出…