news 2026/7/10 4:30:45

PTA L1-011 A-B:从字符串中精准“剔除”字符的实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PTA L1-011 A-B:从字符串中精准“剔除”字符的实战解析

1. 从字符串中精准“剔除”字符的实战需求

在日常编程练习或技术面试中,经常会遇到需要处理字符串的场景。比如这道PTA平台的经典题目L1-011 A-B,要求从字符串A中删除所有在字符串B中出现的字符。这看似简单的需求,实际上考察了开发者对字符串操作、函数调用和边界条件处理的综合能力。

我第一次遇到这类问题时,下意识想到的是用双重循环暴力匹配。但后来发现,C语言标准库中其实有现成的工具函数可以优雅解决。就像木匠不会用手去掰断木板,而是会选择合适的锯子一样,strchr函数就是我们处理这类问题的利器。

这道题有几个关键约束条件需要注意:字符串长度不超过10^4、由可见ASCII码和空白字符组成。这意味着我们需要考虑效率问题,同时要正确处理空格等特殊字符。在实际项目中,这种字符串清洗操作也很常见,比如过滤敏感词、处理用户输入等场景。

2. 解题思路与核心算法

2.1 问题拆解与解决思路

解决这个问题可以分为三个关键步骤:输入处理、字符过滤和结果输出。最核心的部分是如何高效判断字符是否需要删除。我尝试过几种方法后,发现strchr函数查找法既简洁又高效。

具体思路是:遍历字符串A的每个字符,用strchr在字符串B中查找该字符。如果找到就跳过,否则保留。这就像是在做一道筛选题,把不符合条件的选项都剔除掉。这种方法的时间复杂度是O(n*m),对于题目给出的数据规模完全够用。

我曾经在一个实际项目中遇到过类似需求,需要过滤用户输入中的特殊符号。最初用双重循环实现,后来重构为使用strchr后,代码可读性明显提升,执行效率也有所改善。

2.2 strchr函数深度解析

strchr函数的原型是:

char *strchr(const char *str, int ch);

它的工作原理很像一个尽职的哨兵:从字符串str的起始位置开始逐个检查,直到找到字符ch或者走到字符串末尾。找到就返回该字符的地址,否则返回NULL。

这里有个容易踩坑的地方:strchr的第二个参数是int类型,但实际传入的是char类型。这是因为C语言中字符常量实际上是整数。我曾经因为忽略这点导致过编译警告,后来养成了显式类型转换的习惯。

使用strchr时还需要注意:

  • 它对大小写敏感,'a'和'A'会被视为不同字符
  • 可以查找空字符'\0',这在某些特殊场景下有用
  • 如果要查找的字符不在字符串中,返回的NULL指针需要特别处理

3. 完整代码实现与逐行解读

3.1 基础版本实现

先看一个基础实现版本:

#include <stdio.h> #include <string.h> #define MAX_LEN 10001 int main() { char strA[MAX_LEN] = {0}; char strB[MAX_LEN] = {0}; fgets(strA, MAX_LEN, stdin); fgets(strB, MAX_LEN, stdin); int length = strlen(strA); for(int i = 0; i < length; i++) { if(!strchr(strB, strA[i])) { putchar(strA[i]); } } return 0; }

这个版本有几个值得注意的改进点:

  1. 使用fgets替代gets,避免缓冲区溢出风险
  2. 定义了MAX_LEN常量,提高代码可维护性
  3. 使用putchar输出单个字符,比printf更高效

3.2 边界条件处理

在实际测试中,我发现几个需要特别注意的边界情况:

  1. 输入字符串包含换行符:fgets会保留换行符,可能需要特殊处理
  2. 空字符串输入:需要确保程序不会崩溃
  3. 字符串B中有重复字符:虽然不影响结果,但可能影响性能

改进后的处理逻辑:

// 去除fgets读取的换行符 strA[strcspn(strA, "\n")] = '\0'; strB[strcspn(strB, "\n")] = '\0'; // 处理空字符串 if(strlen(strA) == 0) { return 0; }

4. 性能优化与替代方案

4.1 使用哈希表优化

当字符串B很长时,反复调用strchr会导致性能下降。这时可以用哈希表思想进行优化:

int charMap[256] = {0}; // ASCII码哈希表 // 构建字符映射表 for(int i = 0; i < strlen(strB); i++) { charMap[(unsigned char)strB[i]] = 1; } // 过滤字符 for(int i = 0; i < strlen(strA); i++) { if(!charMap[(unsigned char)strA[i]]) { putchar(strA[i]); } }

这种方法将时间复杂度降低到O(n+m),特别适合处理大规模数据。我在一次编程竞赛中就靠这个优化通过了最后的大数据测试用例。

4.2 其他语言实现对比

作为拓展,我们看看其他语言如何实现相同功能:

Python版本:

strA = input() strB = input() print(''.join(c for c in strA if c not in strB))

Java版本:

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String strA = sc.nextLine(); String strB = sc.nextLine(); System.out.println(strA.replaceAll("["+strB+"]", "")); } }

相比之下,C语言的实现虽然代码量稍多,但执行效率最高,也更适合理解底层原理。

5. 常见问题与调试技巧

在实际编码过程中,我遇到过几个典型问题:

  1. 缓冲区溢出:早期使用gets函数时,输入超长字符串会导致程序崩溃。改用fgets并指定缓冲区大小后解决。

  2. 空格处理:最初没注意到题目要求保留空格,导致输出结果异常。后来添加了测试用例"I love coding"和"lo"来验证空格处理。

  3. 性能问题:第一次提交时,对超长字符串(10000字符)处理超时。通过优化循环内部逻辑,避免重复计算strlen后通过。

调试时可以使用的技巧:

  • 添加打印语句输出中间结果
  • 使用边界值测试(空字符串、全空格字符串等)
  • 用valgrind检查内存问题

6. 实际应用场景扩展

这个算法虽然简单,但在实际开发中有很多应用场景:

  1. 敏感词过滤:将敏感词库作为字符串B,用户输入作为字符串A
  2. 数据清洗:去除文本中的特定符号或不可见字符
  3. 密码策略验证:检查密码是否包含不允许的字符

我曾经参与开发的一个评论系统就使用了类似技术,过滤掉广告中的联系方式。相比正则表达式,这种实现更轻量高效。

在后续学习中,可以尝试扩展这个算法:

  • 支持通配符匹配
  • 实现大小写不敏感的过滤
  • 处理多字节字符(如UTF-8编码)

7. 学习建议与资源推荐

想要深入掌握字符串处理,我建议从以下几个方面入手:

  1. 熟练掌握C标准库函数

    • strlen, strcpy, strcat等基础函数
    • strchr, strstr等查找函数
    • strtok等分割函数
  2. 理解字符串底层表示

    • 字符编码(ASCII, Unicode)
    • 内存布局与结束符
    • 指针与字符数组的关系
  3. 多做练习

    • PTA平台上的字符串相关题目
    • LeetCode上的String分类题目
    • 自己实现常用字符串函数

推荐几本我读过后觉得不错的资源:

  • 《C程序设计语言》(K&R)中的字符串章节
  • 《算法导论》中的字符串匹配算法
  • glibc源码中的字符串函数实现

最后分享一个我调试字符串问题时的小技巧:用十六进制形式输出字符串,可以清晰看到每个字节的值,特别适合排查编码和边界问题。比如:

for(int i = 0; i < len; i++) { printf("%02x ", (unsigned char)str[i]); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 8:11:23

3步轻松提取视频中的PPT:extract-video-ppt完整使用指南

3步轻松提取视频中的PPT&#xff1a;extract-video-ppt完整使用指南 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾经花费数小时观看教学视频&#xff0c;只为截图保存那些…

作者头像 李华
网站建设 2026/7/6 8:30:31

Parsec虚拟显示器:3步创建高性能Windows虚拟显示器的终极指南

Parsec虚拟显示器&#xff1a;3步创建高性能Windows虚拟显示器的终极指南 【免费下载链接】parsec-vdd ✨ Perfect virtual display for game streaming 项目地址: https://gitcode.com/gh_mirrors/pa/parsec-vdd 你是否曾想过扩展电脑屏幕却不想购买昂贵的物理显示器&a…

作者头像 李华
网站建设 2026/7/6 7:24:48

TVA与具身智能之间复杂且深刻的结构性关联(2)

前沿技术介绍&#xff1a;AI智能体视觉&#xff08;TVA&#xff0c;Transformer-based Vision Agent&#xff09;是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术&#xff0c;属于“物理AI” 领域的一种全新技术形态&#xff0c;完成了从“虚拟世界”到“…

作者头像 李华
网站建设 2026/7/9 3:38:48

告别音乐格式枷锁:ncmdumpGUI让你真正拥有网易云音乐

告别音乐格式枷锁&#xff1a;ncmdumpGUI让你真正拥有网易云音乐 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换&#xff0c;Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经遇到过这样的尴尬时刻&#xff1f;…

作者头像 李华
网站建设 2026/7/4 23:56:10

科技助老暖心就医!天津职业技术师范大学团队打造CareLink·暖医随行无障碍就医导航助手破解老年人就医难题

当前我国老龄化进程持续加快&#xff0c;老年人就医迷路、智能设备操作困难、就医流程繁琐等痛点愈发突出。针对这一社会刚需&#xff0c;天津职业技术师范大学刘景带领大学生创业团队&#xff0c;在老师指导下&#xff0c;依托人工智能、物联网与室内定位技术&#xff0c;研发…

作者头像 李华
网站建设 2026/7/6 22:21:57

Tomcat项目本地部署

测试tomcat1.进入tomcat中bin文件夹下&#xff0c;启动tomcat&#xff0c;双击startup.bat如果启动闪退&#xff0c;通常是 JAVA_HOME 环境变量未正确配置&#xff0c;或Tomcat路径包含中文/空格2.打开浏览器&#xff0c;访问 http://localhost:8080。如果看到Tomcat的默认欢迎…

作者头像 李华