游乐游手机版
首页/AI教程/文章详情

Go语言实现字符串中字母与特殊字符的反转

时间:2026-05-30 09:37
2026年5月30日:字符串反转算法题精讲——先逆序字母再翻转特殊字符。给定一个仅包含小写英文字母与特殊字符的字符串,要求分两步操作:首先将所有小写字母的相对顺序整体颠倒,重新放回原位;接着将所有特殊字符的相对顺序整体翻转,同样放回原位。最终输出变换后的字符串。本题源自力扣第3823题,字符串长度范

2026年5月30日:字符串反转算法题精讲——先逆序字母再翻转特殊字符。给定一个仅包含小写英文字母与特殊字符的字符串,要求分两步操作:首先将所有小写字母的相对顺序整体颠倒,重新放回原位;接着将所有特殊字符的相对顺序整体翻转,同样放回原位。最终输出变换后的字符串。本题源自力扣第3823题,字符串长度范围为1至100,特殊字符限定为“!@#$%^&*()”。

举一个极端边界案例:输入全特殊字符 !@#$%^&*(),输出应为 )(*&^%$#@!。为什么是这个结果?因为字符串中没有字母,第一步反转字母实际上不会有任何操作,第二步反转特殊字符相当于直接反转整个字符串。理解了这一逻辑,我们就能深入探讨具体实现细节了。

一、分步骤执行过程(输入:!@#$%^&*())

输入字符串:!@#$%^&*()。全程不含小写字母,全部为特殊字符,非常适合用来验证算法的边界处理能力。

步骤1:执行 reverseByType 函数,将字符串转为字节切片

首先将字符串转换成字节数组 t,数组元素依次为:!、@、#、$、%、^、&、*、(、),共10个元素。

步骤2:第一次调用 reverse 函数(处理小写字母)

  • 判断条件:是小写字母(a-z)
  • 执行逻辑:
    1. 初始化双指针 i=0(左指针)、j=9(右指针);
    2. 左指针向右遍历:所有元素都是特殊字符,不满足“是小写字母”的条件,左指针停下;
    3. 右指针向左遍历:同样都是特殊字符,不满足条件,右指针停下;
    4. 交换左右指针指向的元素,然后指针向内移动;
    5. 循环持续到指针相遇,最终结果:字节数组被完全反转!
  • 第一次反转后字节数组:)、(、*、&、^、%、$、#、@、!

补充:如果字符串包含字母的执行逻辑(帮助理解)

举个例子:输入 a!b@c

  1. 第一次 reverse(判断:是字母):
    • 跳过字母,只交换特殊字符?不,逻辑是:满足条件(是字母)就跳过,不满足(特殊字符)就停下交换;
    • 最终效果:字母的相对顺序整体反转,放回原位置,特殊字符位置不变;
    • 示例:a!b@c → 字母反转后 → c!b@a

步骤3:第二次调用 reverse 函数(处理特殊字符)

  • 判断条件:不是小写字母(即特殊字符)
  • 执行逻辑:
    1. 此时字节数组是 )、(、*、&、^、%、$、#、@、!
    2. 遍历所有元素:全是特殊字符,都满足“不是小写字母”的条件;
    3. 双指针会直接遍历到相遇,没有任何字符需要交换;
  • 第二次反转后字节数组:保持 )、(、*、&、^、%、$、#、@、! 不变。

步骤4:将字节切片转回字符串

最终得到字符串:)(*&^%$#@!,与题目要求的输出完全一致。

二、时间复杂度分析

  1. 字符串转字节切片:O(n),n是字符串长度;
  2. 第一次reverse函数:双指针遍历整个切片一次,O(n);
  3. 第二次reverse函数:双指针遍历整个切片一次,O(n);
  4. 字节切片转回字符串:O(n);

总时间复杂度:O(n) + O(n) + O(n) + O(n) = O(n)。线性复杂度,执行时间与字符串长度成正比,性能优异。

三、额外空间复杂度分析

额外空间指除了输入数据外,程序额外开辟的内存空间。

  1. 代码中将字符串转为字节切片 t,开辟了长度为n的字节数组,占用O(n)空间;
  2. 所有变量(指针i、j、临时变量等)都是常数级空间,O(1);

总额外空间复杂度:O(n)。需要额外开辟和输入字符串等长的存储空间,属于可接受的线性开销。

总结

  1. 执行过程:输入全特殊字符→转字节切片→第一次反转字母(实际反转整个字符串)→第二次反转特殊字符(无交换)→转回字符串;
  2. 时间复杂度:O(n)(线性复杂度);
  3. 额外空间复杂度:O(n)(需要等长的字节切片存储数据)。

Go完整代码如下:

package main

import ("fmt")

func reverse(t []byte, f func(byte) bool) {
    i, j := 0, len(t)-1
    for i < j {
        for i < j && f(t[i]) {
            i++
        }
        for i < j && f(t[j]) {
            j--
        }
        t[i], t[j] = t[j], t[i]
        i++
        j--
    }
}

func reverseByType(s string) string {
    t := []byte(s)
    reverse(t, func(ch byte) bool { return 'a' <= ch && ch <= 'z' })
    reverse(t, func(ch byte) bool { return !('a' <= ch && ch <= 'z') })
    return string(t)
}

func main() {
    s := "!@#$%^&*()"
    result := reverseByType(s)
    fmt.Println(result)
}

Python完整代码如下:

# -*-coding:utf-8-*-
def reverse(t, condition_func):
    """按条件反转字符序列"""
    i, j = 0, len(t) - 1
    t_list = list(t)  # 转换为列表以便修改
    while i < j:
        # 从左向右找到第一个不满足条件的字符
        while i < j and condition_func(t_list[i]):
            i += 1
        # 从右向左找到第一个不满足条件的字符
        while i < j and condition_func(t_list[j]):
            j -= 1
        # 交换
        t_list[i], t_list[j] = t_list[j], t_list[i]
        i += 1
        j -= 1
    return ''.join(t_list)

def reverse_by_type(s):
    """按字符类型反转字符串"""
    # 第一次反转:对小写字母进行反转
    s = reverse(s, lambda ch: 'a' <= ch <= 'z')
    # 第二次反转:对非小写字母进行反转
    s = reverse(s, lambda ch: not ('a' <= ch <= 'z'))
    return s

def main():
    s = "!@#$%^&*()"
    result = reverse_by_type(s)
    print(result)

if __name__ == "__main__":
    main()

C++完整代码如下:

#include 
#include 
#include 
#include 

void reverse(std::string& t, bool (*f)(char)) {
    int i = 0, j = t.length() - 1;
    while (i < j) {
        // 从左向右找到第一个不满足条件的字符
        while (i < j && f(t[i])) {
            i++;
        }
        // 从右向左找到第一个不满足条件的字符
        while (i < j && f(t[j])) {
            j--;
        }
        // 交换
        std::swap(t[i], t[j]);
        i++;
        j--;
    }
}

std::string reverseByType(const std::string& s) {
    std::string t = s;  // 复制字符串
    // 第一次反转:对小写字母进行反转
    reverse(t, [](char ch) -> bool {
        return 'a' <= ch && ch <= 'z';
    });
    // 第二次反转:对非小写字母进行反转
    reverse(t, [](char ch) -> bool {
        return !('a' <= ch && ch <= 'z');
    });
    return t;
}

int main() {
    std::string s = "!@#$%^&*()";
    std::string result = reverseByType(s);
    std::cout << result << std::endl;
    return 0;
}

来源:https://bbs.huaweicloud.com/blogs/478389
上一篇单卡爆改MiniCPM-V 1.3B 支持图像视频OCR多轮对话 下一篇Harness Engineering工程化教程:AI Agent复杂长任务从入门到精通
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
AI高效生成大班科学实验教学PPT下载 提升课堂质量与趣味性
AI教程 · 2026-05-30

AI高效生成大班科学实验教学PPT下载 提升课堂质量与趣味性

```html 对于众多教师而言,大班教学既是日常挑战,也是必须面对的常态。当教室内坐着几十甚至上百名满怀期待的学生时,如何高效准备一堂既生动清晰又能牢牢抓住所有人注意力的课程?PPT 往往是那位不可或缺的“得力助手”。然而,难题也随之浮现:内容要充实,设计需美观,还要贴合不同教学主题——若从头自行

AI提升班会质量:PPT主题总结与未来计划范文
AI教程 · 2026-05-30

AI提升班会质量:PPT主题总结与未来计划范文

使用情景 在校园生活中,主题班会是班级凝聚力的重要体现,堪称一场“全员聚会”。同学们齐聚一堂,交流学习心得、分享生活体会,同时回顾和反思近期的整体表现。然而,每当提到“主题班会”,不少同学便会感到些许压力:如何准备?怎样才能将内容整理得既有条理、有深度,又不失趣味性?这时,PPT便成为了高效组织的得

实测ToDesk AI对比QClaw:更省额度回答更详细
AI教程 · 2026-05-30

实测ToDesk AI对比QClaw:更省额度回答更详细

前言 最近一段时间,我连续体验了几款主打“Claw”能力的桌面智能助手,最初只是想看看它们是否只是“披着AI外壳的聊天工具”。然而,真正上手体验后,感受非常明确:ToDesk AI(ToClaw)更像一个能够直接落地执行任务的桌面助手,而不只是一个会聊天、能生成内容的模型入口。 很多人在评估这类产品

大班幼儿教育PPT制作免费技巧轻松掌握告别烦恼
AI教程 · 2026-05-30

大班幼儿教育PPT制作免费技巧轻松掌握告别烦恼

使用情景 在幼儿园大班的教学场景中,PPT早已成为老师们不可或缺的课堂助手。无论是日常的课件讲解、主题活动的组织,还是家长会上的总结汇报,一份优质的PPT都能让信息传递更加直观,同时有效吸引孩子们的注意力。 不过,要想把大班PPT做得既美观又实用,确实需要花费不少心思。内容既要丰富有趣,视觉上又要具

2026最新版Claude Opus 4.7国内使用全攻略:价格不变能力翻倍
AI教程 · 2026-05-30

2026最新版Claude Opus 4.7国内使用全攻略:价格不变能力翻倍

比Opus 4 6更强的新一代模型Opus 4 7终于正式发布。就在OpenAI不断扩展Codex功能的同时,Anthropic迅速推出了Opus 4 7——而且这次带来的确实是实质性升级。(目前已经全量上线,用户可以直接上手体验。)那么,Opus 4 7究竟有哪些突破?先给个结论:这不是一次简单的