PAT 习题解析:高效统计字符串中各类字符的实用技巧

C语言字符统计实战:PAT习题8-9保姆级解析(附完整代码) 本文以PAT习题8-9为例,提供C语言字符统计的保姆级解析与完整代码。文章深入探讨了从基础指针遍历到使用标准库函数`<ctype.h>`的进阶优化,并分享了提升代码鲁棒性、可扩展性的工程级实践,帮助读者掌握字符串处理的核心技能。 阅读详情

1. 从一道PAT习题说起:为什么字符统计这么重要?

很多刚开始学C语言的朋友,一看到字符串处理就头疼。指针绕来绕去,字符分类判断一堆 if-else,写出来的代码又长又容易出错。我记得我刚开始刷PAT(Programming Ability Test)题目的时候,就卡在过类似“分类统计各类字符个数”这种题上。题目要求看起来很简单:给你一个字符串,数清楚里面有多少个大写字母、小写字母、空格、数字,还有剩下的其他字符,然后按顺序输出五个数字。

但真动手写,问题就来了。比如,字符串结束标志 \0 处理了吗?指针移动对了没?if-else 的判断顺序会不会有逻辑漏洞?最后输出的格式是不是严格匹配?这些细节,任何一个没注意到,裁判系统那个“答案错误”的提示就跳出来了,让人特别有挫败感。

其实,这道题就像是一个基本功的试金石。它考察的不是什么高深的算法,而是你对C语言最核心的两个概念——字符串和指针——是不是真的理解了、用熟了。字符串在C里其实就是字符数组,而处理数组,指针又是最高效的工具。能把这道题写得又快又准,说明你已经过了新手村,对内存操作有了最直接的感知。

更重要的是,这个“数字符”的需求,在真实开发里太常见了。我做过一个日志分析的小工具,第一步就是快速扫描日志文件,统计不同级别的日志(INFO, WARN, ERROR这些标记)出现了多少次,这本质上就是在做字符或字符串的模式匹配与计数。再比如,做用户注册功能时,你得校验用户输入的密码强度:包含多少大写字母、多少数字、多少特殊字符。你看,底层逻辑和我们这道PAT习题一模一样。

所以,今天我们就以这道经典的PAT习题(习题8-9)为引子,不光是给出一个“正确答案”,更要一起深挖下去。我会分享几种不同的实现思路,从最直白的到最高效的,聊聊指针遍历字符串的那些核心技巧,还有怎么避免常见的“坑”。咱们的目标是,下次再遇到类似问题,你能毫不犹豫地写出既正确又漂亮的代码。

2. 理解战场:函数接口与裁判程序

在动手写代码之前,我们必须先把题目给的“战场地图”研究透。很多同学丢分,不是算法不会,是没看懂题目规则。我们先把题目给的关键信息拆解一下。

题目给的函数接口定义非常明确:

void StringCount( char *s );

就这一个参数,char *s,一个指向字符的指针,也就是传入的字符串。这里有个关键点:在C语言中,数组名在作为函数参数传递时,会退化成指向其首元素的指针。所以,无论你接收到的是 char s[] 还是 char *s,在函数内部,你都可以用指针的方式来遍历它。

再看裁判测试程序样例:

#include <stdio.h>
#define MAXS 15

void StringCount( char *s );
void ReadString( char *s ); /* 由裁判实现,略去不表 */

int main()
{
    char s[MAXS];
    ReadString(s);
    StringCount(s);
    return 0;
}
/* Your function will be put here */

这里透露了几个重要信息:

  1. 头文件与常量:只包含了 <stdio.h>,意味着我们只能使用标准的输入输出函数。定义了一个宏 MAXS 为15,说明字符串最大长度是14(还要留一个位置给 \0 结束符)。我们在实现函数时,绝对不能越界访问,虽然我们的遍历靠 \0 结束,但心里要有这个长度概念。
  2. 输入已处理:ReadString 函数由裁判程序实现,它已经帮我们把用户输入读入到字符数组 s 里了。这意味着我们不需要、也不应该在 StringCount 函数里再去调用 scanf 或 gets 之类的输入函数。我们的任务纯粹是处理已经存在的字符串。
  3. 输出要求:题目说“在一行内按照:大写字母个数 小写字母个数 空格个数 数字个数 其它字符个数的格式输出”。注意看样例输出:2 2 1 3 4。这意味着五个数字之间用一个空格隔开,最后没有空格,也没有换行(虽然通常 printf 后不加 \n 在控制台看起来有点怪,但必须严格遵守裁判格式)。输出必须用 printf 完成。

我刚开始就犯过一个错误:自己测试时,习惯性地在 printf 里加了换行符 \n,结果在PAT系统里死活通不过,因为系统是严格进行字符串比对,多一个看不见的换行符都不行。所以,仔细阅读输出格式要求,是刷题的第一要务。

3. 基础解法:指针遍历与条件分支

这是最直观、最容易想到的方法,也是我们一步步理解过程的起点。我们先来看代码,然后我带你一行行分析其中的门道。

void StringCount( char *s ) {
    int capital = 0, lower = 0, blank = 0, figure = 0, special = 0;
    while (*s != '\0') {
        if (*s >= 'A' && *s <= 'Z') {
            capital++;
        } else if (*s >= 'a' && *s <= 'z') {
            lower++;
        } else if (*s == ' ') {
            blank++;
        } else if (*s >= '0' && *s <= '9') {
            figure++;
        } else {
            special++;
        }
        s++;
    }
    printf("%d %d %d %d %d", capital, lower, blank, figure, special);
}

第一步:初始化计数器。我们定义了五个整型变量,分别对应大写字母(capital)、小写字母(lower)、空格(blank)、数字(figure)、其他字符(special)。一定要记得初始化,C语言中局部变量如果不初始化,它的值是随机的“垃圾值”,直接用来累加会得到错误结果。

第二步:核心循环——指针遍历。while (*s != '\0') 是经典的C语言字符串遍历方式。\0 是字符串的结束标志。只要指针 s 所指向的字符不是 \0,循环就继续。这里 *s 是“解引用”操作,取得指针当前指向的字符。

第三步:分类判断。这里用了一个 if-else if-else 的链式结构。顺序很重要:

  1. 先判断是否为大写字母:*s >= 'A' && *s <= 'Z'。这里直接比较字符的ASCII码。在ASCII表中,'A' 到 'Z','a' 到 'z','0' 到 '9' 都是连续排列的,所以可以用这种范围判断,非常方便。
  2. 然后是小写字母。
  3. 接着是空格。注意,空格是一个单独的字符 ' ',不要写成空字符 '\0'。
  4. 再是数字。
  5. 最后,所有前面都没匹配上的,统统归到 else 分支,算作其他字符。这个分支必须放在最后。

为什么这个顺序是合理的? 试想,如果把 else 分支放到前面,或者把空格判断放到数字判断后面,会发生什么?逻辑就全乱了。这种链式判断,条件越严格、越具体的应该越靠前,兜底的、范围最广的放最后。

第四步:移动指针。s++ 这一句千万不能漏!它让指针 s 指向下一个字符的内存地址。没有它,指针永远停在字符串开头,循环就成了死循环。

第五步:输出结果。按照题目要求的格式,用 printf 一次性输出五个变量,中间用空格隔开。

这个解法清晰易懂,是满分答案。但它真的是最优的吗?从逻辑上看,每个字符都要经过最多5次判断(如果它是其他字符)。对于短字符串没问题,但如果字符串极长,有没有优化空间呢?我们后面再聊。

4. 思维进阶:优化判断逻辑与代码风格

基础解法能拿分,但如果我们想追求更高效、更优雅的代码,就有不少可以琢磨的地方。这一部分,我们来聊聊几种优化思路。

4.1 使用字符分类函数(ctype.h)

其实,C标准库 <ctype.h> 提供了一组现成的函数来判断字符类型,这让我们的代码更简洁,意图更清晰。

#include <ctype.h> // 注意需要包含这个头文件

void StringCount( char *s ) {
    int capital = 0, lower = 0, blank = 0, figure = 0, special = 0;
    for (; *s != '\0'; s++) {
        if (isupper(*s)) {        // 是否为大写字母
            capital++;
        } else if (islower(*s)) { // 是否为小写字母
            lower++;
        } else if (isspace(*s)) { // 是否为空白字符(注意:包括空格、制表符、换行等)
            // 题目明确只统计空格,所以这里需要额外判断
            if (*s == ' ') {
                blank++;
            } else {
                special++; // 其他空白字符如\t,\n算作其他字符
            }
        } else if (isdigit(*s)) { // 是否为数字
            figure++;
        } else {
            special++;
        }
    }
    printf("%d %d %d %d %d", capital, lower, blank, figure, special);
}

使用库函数的好处是可读性更强,isupper、islower 一眼就知道在干嘛。但这里有个坑:isspace(*s) 判断的是“空白字符”,包括空格 ' '、换行 \n、制表符 \t 等。而题目只要求统计空格。所以,如果我们直接用 isspace,遇到输入里的换行符(虽然ReadString可能不会读入换行)或者制表符,就会错误地计入空格。因此,用库函数时一定要小心,看清题目要求。对于这道明确要求“空格”的题,直接判断 *s == ' ' 更安全。

4.2 优化判断顺序:基于字符出现概率

这是一个很有趣的优化思路。在我们不确定字符分布时,基础解法的判断顺序是没问题的。但如果我们知道输入字符串中某些字符类型出现的概率特别高或特别低,就可以调整 if-else 的顺序,让高频字符更早被判断到,从而减少平均判断次数。

比如,在一段普通的英文文章或代码注释中,小写字母的出现频率通常远高于大写字母和数字。那么,我们可以把小写字母的判断提前:

if (*s >= 'a' && *s <= 'z') {
    lower++;
} else if (*s >= 'A' && *s <= 'Z') {
    capital++;
} else if (*s == ' ') {
    blank++;
} else if (*s >= '0' && *s <= '9') {
    figure++;
} else {
    special++;
}

对于一篇以英文小写为主的文章,大部分字符在第一次判断时就结束了,效率更高。当然,PAT的测试用例可能很短,优化效果微乎其微,但这种根据数据特征调整算法的思维,在处理大规模数据时非常宝贵。

4.3 使用Switch语句?不推荐

有些同学可能会想,能不能用 switch 语句?比如:

switch (*s) {
    case 'A' ... 'Z': capital++; break;
    // ... 其他case
}

很遗憾,C语言的 switch 的 case 标签必须是整型常量表达式,不支持 'A' ... 'Z' 这样的范围语法(这是GCC的扩展,不是标准C,可移植性差)。如果为52个字母每个都写一个 case,代码会冗长到无法忍受。所以,对于范围判断,if-else if 链或库函数是更合适的选择。

4.4 代码风格与健壮性

最后聊聊代码风格。即使逻辑正确,清晰的代码也能让你在检查、调试时事半功倍。

  • 变量命名:capital, lower 就比 a, b, c 好懂得多。
  • 适当注释:对复杂的逻辑或容易误解的地方加注释。比如,为什么 else 分支放最后。
  • 考虑边界:虽然题目保证输入有效,但好习惯是思考:如果传入的指针 s 是 NULL 怎么办?一个健壮的函数可以增加一句 if (s == NULL) return; 来防止程序崩溃。

5. 深入原理:指针操作与内存视角

理解了“怎么做”之后,我们有必要深入一层,看看“为什么”可以这么做。这能帮你真正驾驭指针,而不是死记硬背。

当我们写下 char *s 作为参数时,函数得到的是字符串首字符的内存地址。while (*s != '\0') 这个循环,本质上是在连续地读取内存。

想象内存像一排连续的格子,每个格子放一个字符(比如 'H', 'e', 'l', 'l', 'o', '\0')。指针 s 最初指向 'H' 的格子。

  • *s 操作:看看当前格子里放着什么值。
  • 根据值进行分类判断和计数。
  • s++ 操作:这不是把格子的值加1,而是让指针移动到下一个格子。因为 s 是 char * 类型,s++ 会让地址值增加 sizeof(char),也就是1个字节,正好指向下一个字符。

这个过程直到遇到值为 \0(数字0)的格子才停止。\0 就像一个终止符,告诉程序:“字符串到此结束,后面的内存可能不属于它了。”

数组表示法与指针表示法的等价性:在函数内部,s[i] 这种数组下标写法,和 *(s+i) 这种指针写法是完全等价的。编译器会把 s[i] 转换成 *(s+i) 来执行。所以,你也可以用 for (int i = 0; s[i] != '\0'; i++) 来遍历,对于初学者可能更直观。但理解指针的移动,是理解C语言内存操作的关键一步。

一个常见的错误:在循环里写 while (*s++ != '\0'),然后把判断和计数都放在循环体内。这样写非常容易出错,因为 *s++ 这个表达式本身会先取 s 指向的值进行比较,然后再移动 s。你需要非常小心地安排计数语句的位置,否则可能漏数第一个字符或多数最后一个 \0。我建议新手还是老老实实把 s++ 单独作为循环体里的一句,逻辑更清晰。

6. 举一反三:解决更复杂的字符统计问题

掌握了基础方法,我们就可以挑战一些变种问题,这也是PAT和实际面试中常考的。

6.1 统计特定单词或子串出现次数

比如,统计字符串中 "the" 这个单词出现的次数(需要考虑大小写吗?需要考虑单词边界吗?)。这就不再是单字符统计,而是需要滑动窗口或状态机的思想了。你可以用指针遍历,当发现 't' 时,检查接下来的 'h' 和 'e' 是否符合,并且检查 't' 前一个字符和 'e' 后一个字符是否是单词边界(如空格、标点或字符串起止)。

6.2 统计出现频率最高的字符

这需要我们将统计结果保存下来,然后找最大值。一种方法是使用一个大小为256的整型数组(对应所有ASCII码字符),初始化为0。遍历字符串时,以字符的ASCII码值作为索引,对数组相应位置的值加1。遍历完成后,再扫描这个计数数组,找到值最大的那个索引,其对应的字符就是出现最频繁的。这种方法叫做哈希表的简单应用,思想非常重要。

// 思路示例
int count[256] = {0}; // 初始化所有计数器为0
char *p = s;
while (*p) {
    count[(unsigned char)(*p)]++; // 将字符转为无符号数作为索引
    p++;
}
int max_count = 0;
char max_char = 0;
for (int i = 0; i < 256; i++) {
    if (count[i] > max_count) {
        max_count = count[i];
        max_char = (char)i;
    }
}
// 此时 max_char 就是出现最多的字符,max_count 是其次数

6.3 在统计时忽略大小写

有时候我们需要将 'A' 和 'a' 视为同一种字母进行统计。这时可以在判断前,先使用 tolower() 或 toupper() 函数(也在 <ctype.h> 中)将字符统一转换为小写或大写,然后再进行分类。例如,统一转小写后,判断 if (tolower(*s) >= 'a' && tolower(*s) <= 'z'),这样无论原字符是大写还是小写,都会被归到“字母”类别下计数。

这些变种问题,核心遍历和分类的思想是不变的,只是判断条件和数据存储结构变得更加复杂。多练习这些题目,能极大地锻炼你的逻辑思维和编码能力。

7. 实战避坑指南与调试技巧

理论讲完了,我们来点实在的。结合我自己的经验,说说写这类代码时最容易踩的坑,以及怎么快速调试。

坑1:忘记移动指针或移动错误。 这是导致死循环的最常见原因。检查循环,确保 s++(或 i++)在合适的位置执行。

坑2:判断条件重叠或顺序错误。 比如先判断了 *s >= '0' && *s <= '9',然后又判断 *s >= 'A' && *s <= 'Z',这没问题。但如果先判断 *s >= 'A' && *s <= 'z'(想同时涵盖大小写),那就错了,因为ASCII码中,'Z'(90)和 'a'(97)之间还有几个特殊字符([ \ ] ^ _ )。这个范围会把它们也算成字母。

坑3:输出格式不对。 PAT系统是严格比对输出的。多一个空格、少一个空格、多一个换行、少一个换行,都会判错。最好的方法是,直接复制题目样例输出的格式到你的 printf 语句里,然后只替换数字为变量。自己测试时,也可以用 printf("|%d %d %d %d %d|", ...) 在输出前后加个特殊符号,看看空格和换行符到底在哪。

坑4:未初始化计数器。 这是C语言新手必踩之坑。局部变量不初始化,值是随机的。一定要养成 int capital = 0; 的习惯。

调试技巧:

  1. 打印中间状态:在循环里加一句调试用的 printf,比如 printf("当前字符:%c, 指针值:%p\n", *s, s);,可以清楚地看到每个字符是什么,指针是否在正常移动。调试完记得删掉。
  2. 使用静态测试用例:自己构造一些有代表性的字符串进行测试。
    • 空字符串 "":所有计数应为0。
    • 全空格字符串 " "。
    • 混合边界字符串,如 "A a 0 !"。
    • 包含换行符、制表符的字符串(如果题目允许输入这些)。
  3. 在纸上模拟:对于复杂的指针操作或逻辑,拿一张纸,画出内存格子,一步步模拟指针移动和变量变化。这是理解程序运行过程最有效的方法。

这道“分类统计字符”的题,就像学习编程路上的一个老朋友,看似简单,却总能检验出你对基础知识的掌握是否扎实。希望今天不仅给了你一个答案,更帮你理清了背后的思路、优化方法和避坑指南。编程能力的提升,就在于把每一道这样的基础题吃透、练熟,直到你能自然地写出高效可靠的代码。下次遇到字符串处理,不妨先想想指针怎么走,条件怎么判,相信你会更加从容。

PAT甲级题目解析和知识点分类整理 个人博客:https://maxusun.github.io/ 转载请注明出处 今天整理电脑,发现了去年为了考研浙大计算机整理的PAT资料。现在考研已经尘埃落定。想到当时盲目刷题浪费了好多时间,在这里希望将整理的东西放到网上,方便后来者学习。 PAT的命题趋势 将PAT甲级中的题目从第一题刷到最后一题,可以明显感受到,PAT甲级的题目风格发生了很明显的变化。从早期的模拟型题目变成了后来以数据结构和算法为主的固定题型。如果时间紧迫的话,可以只刷后一般的题目,放弃前一半的题目,因为前一半题目的出题风格已经过时了 阅读详情

相关推荐

PAT乙级编程题解析:字符串处理与模拟算法实战

字符串处理是编程中的基础且核心的技术,它涉及对字符序列的遍历、查找、分割、拼接和转换等操作。其原理在于通过索引或迭代器访问字符串中的每个元素,结合条件判断和状态管理,实现对特定模式的识别与数据提取。掌握高效的字符串处理技巧,能显著提升代码在文本解析、数据清洗和协议分析等场景下的性能与健壮性。在工程实践中,合理运用如C++标准库中的string类,可以简化开发流程,而模拟算法则是将问题描述转化为一步步可执行代码的关键。本文以PAT乙级考试中的典型题目为例,深入探讨了如何运用字符串处理和模拟算法解决实际问题,并

weixin_31412781的博客 211

knative技术应用

事件流处理:构建基于 Knative Eventing 的实时数据管道,将来自多个源头(如日志、传感器数据、交易记录等)的事件汇聚、转换、过滤后发送至流处理引擎(如 Apache Flink、Kafka Streams)进行实时分析。- 服务解耦:借助 Knative Eventing 构建基于事件通信的微服务架构,各服务间通过发布和订阅事件进行交互,降低服务间的直接依赖,提高系统的弹性和可扩展性。

易之阴阳,量子纠缠,道之一体,缘起性空 487

告别手动脚本!用TSMaster Python小程序5分钟搞定CAN报文自动发送

本文介绍了如何使用TSMaster的Python小程序功能快速实现CAN报文自动发送,大幅提升汽车电子测试效率。通过简洁的Python代码示例,展示了如何替代传统手动操作和复杂C脚本,实现周期性发送、动态修改报文内容等常见需求,帮助工程师5分钟内完成自动化配置。

weixin_30292843的博客 503

第2章:Knative 基础架构

Knative是一个构建在Kubernetes之上的Serverless框架,由两个核心组件组成:Serving负责应用托管和自动扩缩容,提供Service/Route/Configuration/Revision等资源对象;Eventing实现事件驱动架构,基于Broker/Trigger等组件处理异步消息流。两个组件协同工作,既能处理同步HTTP请求,又能处理异步事件触发。Serving通过4层资源抽象(Service→Route→Configuration→Revision)管理应用生命周期,支持蓝绿

pizicaiman的专栏 1344

关于Kswapd的理解(一)

关于Kswapd的理解(一) 之前跟踪了MemAvailable的计算方式,其中watermark的计算花了很多精力,在学习的过程中看到一些资料中说watermark是给swapd使用的,于是乎,研究一下看看咯 本部分主要记录两个方面: 对于kswapd这个东西,从初学者(我)的角度出发会考虑哪些内容? 跟踪kswapd 初始化结构部分; 1. KSwapd机制 上图是还没有跟踪kswapd code的时候,对自己提出的一些疑问和自身的理解,主要是如下内容: kswapd 机制用来做什么:内存不足时

And乔的博客 2706

【SEW-伺服电机-Profinet-io通讯控制——伺服配置】

SEW-伺服电机-Profinet-io通讯控制——伺服配置一、本次使用配置说明编写经历受国际形式与疫情影响相关资料查询阅读测试验证不易二、伺服配置流程1.基本准备条件2.硬件-电路连接3.设备在线连接4.软件-参数配置5.手动运行测试6.PN-IO自动控制配置8.PLC1200硬件组态9.PLC软件编程10.调试故障分析三、总结四、参考 一、本次使用配置说明编写经历 受国际形式与疫情影响 由于近期受国际形式影响以及全球疫情影响,Siemens等常用产品供货期与供货量严重受限,项目上不得不采取选用其它替代产

qq_39024187的博客 1万+

【Knative系列】看完这篇还不懂 Knative 流量转发的原理,你来打我~(史上最详细)

本文主要讲解 Knative serving 系统及组件: 发展历程 Knative 是谷歌开源的 serverless 架构方案,旨在提供一套简单易用的 serverless 方案,把 serverless 标准化。目前参与的公司主要是 Google、Pivotal、IBM、Red Hat,2018年7月24日才刚刚对外发布,当前还处于快速发展的阶段(3.4k star, 3.3k issue)。 Knative 包含 build(已被tekton取代),serving,event三个部分,本文主要介.

云原生Serverless的专栏 7万+

S32K144后门密钥实战:如何用JLINK脚本绕过复位陷阱更新加密固件

本文详细介绍了在S32K144微控制器上,如何利用JLINK脚本绕过调试器默认复位陷阱,实现通过后门密钥安全更新加密固件的实战方案。针对汽车电子现场维护中常见的“解锁-复位-锁定”循环问题,文章提供了完整的JLinkScript定制方法、批处理工具及故障排除指南,帮助工程师高效完成固件升级。

weixin_29175469的博客 136

云原生框架- KNative入门与原理

Knative

gcl的博客 1981

tree_sitter多语言解析器配置实战指南

本文是一份详细的Tree-sitter多语言解析器配置实战指南。文章从零开始,手把手指导如何搭建Python环境、安装指定版本的tree-sitter库、下载并编译多种语言的语法规则,最终构建一个统一的解析器库。通过实战代码演示了如何初始化解析器、解析代码并遍历语法树,旨在帮助开发者高效处理多语言代码分析任务,并分享了高级技巧与常见问题排坑经验。

weixin_29245767的博客 265

【Codex】Codex安装+DeepSeek API接入;无需登录,手把手带你使用codex

好多人使用codex时都卡在验证码登录那一步,今天就来介绍一种方法,不需要登录ChatGPT的账号,自然也就不需要手机验证码了;接入DeepSeek的api,一样可以丝滑使用codex;记录从零开始安装使用codex以及DeepSeek API接入的整个过程。不需要登录openAI;

AnChenliang_1002的博客 3492

Knative详解

Knative 主要由 Build、Serving 和 Eventing 三大核心组件构成。Knative 正是依靠这三个核心组件,驱动着 Knative 这艘 Serverless 巨轮前行。下面让我们来分别介绍一下这三个核心组件。 build Knative Build 是基于现有的 Kubernetes 能力之上,提供的一套标准化、可移植、可复用的容器镜像构建方式。通过在 Kubernetes 上运行复杂的构建任务,Knative Build 使你不必再单独开发和重复这些镜像构建过程, 从而通过系统化

9067

HINT: High-quality INpainting Transformer with Mask-Aware Encoding and Enhanced Attention 训练自己的数据集

HINT(高质量图像修复变换器)通过创新的掩码感知像素洗牌下采样模块(MPD)和空间激活通道注意力层(SCAL),显著提高了图像修复的质量,尤其在大面积缺失区域的情况下。实验表明,HINT在CelebA、CelebA-HQ、Places2和敦煌数据集上超越了现有的最先进模型,提升了图像的细节和结构一致性。

LJ1147517021的博客 310

PAT题解——Basic Level——1093字符串A+B

链接 https://pintia.cn/problem-sets/994805260223102976/problems/1071785884776722432 题面 给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集。要求先输出 A,再输出 B,但重复的字符必须被剔除。 输入格式 输入在两行中分别给出 A 和 B,均为长度不超过 10​^6​​的、由可见 ASCI...

努力中的老周的专栏 7508

基于Simulink的无迹卡尔曼滤波(UKF)SOC高精度估计仿真

本文介绍了基于Simulink的无迹卡尔曼滤波(UKF)在电池SOC高精度估计中的应用。通过无迹变换替代传统EKF的线性化过程,UKF显著提升了SOC估计精度,在强非线性工况下误差可控制在0.5%以内。文章详细阐述了UKF的核心原理,包括Sigma点生成、状态预测和观测更新等关键步骤,并基于Thevenin等效电路模型构建了完整的UKF SOC估算系统。通过Simulink建模和仿真验证,展示了UKF在大电流脉冲、变温工况等复杂场景下的优异性能,其动态响应时间小于30ms,长期累积误差低于0.7%。研究为储

amy_mhd的博客 121

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

PAT乙级1040题解析:高效统计字符串子序列

字符串处理是算法竞赛中的基础技能,通过预处理和组合数学可以显著优化子序列统计问题。本文以PAT考试经典题目为例,详解如何将O(n³)暴力解法优化为O(n)高效算法。关键技术包括前缀和统计、模运算防溢出等工程实践要点,适用于LeetCode等编程题库中的类似问题。通过分析字符串中字符位置关系,建立leftP和rightT预处理数组,实现快速查询任意A字符左右两侧的P/T数量,最终乘积累加得到结果。该模式可拓展至统计各类字符组合场景,是处理大规模字符串问题的通用优化思路。

weixin_33417488的博客 312

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

PAT乙级1092题解析:字符串数字频率统计实战

频率统计是算法设计中的基础问题,其核心原理是通过哈希表结构实现O(1)时间复杂度的元素计数。在字符串处理场景中,这种技术能高效解决字符出现次数统计、模式识别等问题。通过数组或字典实现计数后,结合极值查找算法即可完成典型的最大频率统计需求。PAT乙级1092题正是这类技术的经典应用,考察了字符串遍历、哈希表应用和条件筛选等编程基本功。实际工程中,类似技术广泛应用于日志分析、用户行为统计等大数据处理场景,而优化后的单次遍历算法更能提升海量数据处理效率。掌握这类基础算法,对准备编程能力考试和解决实际工程问题都具有

weixin_30847939的博客 833

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

PAT练习笔记——3.6 字符串处理

2019年9月PAT - 练习笔记——3.6 以下页码标注的是阅读器中实际页码,而不是书本身自印的页码。 第3章 入门篇(1)——入门模拟 3.6 字符串处理 注意 字符的限定范围,见B1014/A1061 目录 B1006 换个格式输出整数 B1021 个位数统计 B1031 查验身份证 B1002 写出这个数 B1009 说反话 B1014/A1061 福尔摩斯的约会 B1024/A10...

qreamly的博客 459

pat 1040 有几个PAT

字符串APPAPT中包含了两个单词PAT,其中第一个PAT是第 2 位(P),第 4 位(A),第 6 位(T);第二个PAT是第 3 位(P),第 4 位(A),第 6 位(T)。 现给定字符串,问一共可以形成多少个PAT? 输入格式: 输入只有一行,包含一个字符串,长度不超过1,只包含P、A、T三种字母。 输出格式: 在一行中输出给定字符串中包含多少个...

weixin_30348519的博客 125

有几个PAT

字符串 中包含了两个单词 ,其中第一个 是第 2 位(),第 4 位(),第 6 位();第二个 是第 3 位(),第 4 位(),第 6 位()。现给定字符串,问一共可以形成多少个 ?输入只有一行,包含一个字符串,长度不超过105,只包含 、、 三种字母。在一行中输出给定字符串中包含多少个 。由于结果可能比较大,只输出对 1000000007 取余数的结果。 输出样例: 代码长度限制16 KB时间限制150 ms内存限制64 MB 我们可以进行暴力枚举,找到一个字符'P'之后,就向后枚

wo_ai_luo_的博客 469

PAT乙级-1040有几个PAT

解题思路:第一次想的是先统计P个数,然后统计A个数,相乘,再统计T个数,相乘,取余;后面想到PAT之间相应关系,一边遍历字符串,一边统计P A T各字符出现的次数,对于P出现了n次,再出现一次A,PA次数毫无疑问为P的次数; 对于PA出现n次,P出现m次,再出现一次A,那么这个A和之前的P构成PA关系,也就是新增加m次PA,不影响之前PA次数,所以共n+m次; 对于PAT次数一样,只要出现...

YuaJniauha的博客 312

Pat乙级 1040 有几个PAT

Pat乙级1040 有几个PAT思路代码 题目网址 https://pintia.cn/problem-sets/994805260223102976/problems/994805282389999616 思路 有点动规的意思,PA出现的次数等于之前PA出现的次数加上当前P的次数(当前字符为’A’时),同理PAT出现的次数等于之前PAT出现的次数加上当前AP出现的次数(当前字符为’T’时)。具体看代码理解。 代码 #include<iostream> #define theNum 100000

ax816的博客 174

PTA 1040 有几个PAT (c语言)

1040 有几个PAT (25 分) 思路:我的大致思路是这样的,在接收这一组字符串的时候先数一下T有几个; 然后在遍历的时候出现T就T的数量减1,出现P就P的数量加1,然后出现A就统计这里有几个PAT; 举个例子: 比如说TTPATP一开始T有三个,然后遍历的时候第一次T减1,第二次T减1(还剩1个),第三次出现P了 P的数量加1; 然后第四次出现A了,就统计这一组有1*1=1个。 代码如下:...

qq_44622401的博客 560

PAT乙级 (其他高效技巧和算法) 1040、1045

1040 有几个PAT 、1045 快速排序

JiangNan_1002的博客 596
上一篇: 拒绝采样微调:如何通过高质量推理路径提升大模型性能
下一篇: 如何用dcluster+goview搭建企业级数据可视化平台?从权限管理到数据源配置全流程指南
cheese
博客等级 码龄25年 100粉丝 1140原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值