PAT乙级1003我要通过的做题笔记

分析题意

得到"答案正确"的条件是:

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;

任意形如 xPATx 的字符串都可以获得"答案正确",其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;

如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

根据题目中的规则,如果aPbTc是正确的,那么aPbATca也是正确的。这里我们可以把字符串中P之前的A的个数看作x,P和T之间的A的个数看作y,T之后的A的个数看作z。

对于初始的合法字符串xPATx,这里x可以为空字符串或者仅由A组成的字符串,此时有x个A在P之前,1个A在P和T之间,x个A在T之后,满足x * 1=x的关系。

当按照规则扩展时,比如从aPbTc变为aPbATca,如果P之前A的个数为a,P和T之间A的个数从b变为b + 1,T之后A的个数从c变为c + a。这种变化始终保持着a * b=c的关系(在原始的xPATx中就是x * 1=x)。

总之就是:只有P,A,T三种字符,PT之间必须有A,P前面的A * PT之间的A == T之后的A

代码思路

确定字符种类

要检测只有三种字符,还有统计其中A,P,T的个数,可以想到利用键值对map,分别检测字符和字符数量,那么就创建一个map<char ,int>类型的键值对变量m。

我们就可以通过遍历字符串的每个字符的方式,来确定字符种类数,和每种字符的个数。

确定A的数量关系

要确定A的数量关系,可以利用下标(索引)来求,我们可以发现字符串索引从0开始,那么P之前A的个数就可以用P的下标来代表,那么我们在循环中一旦遍历到'P',我们就把它的下标存到一个变量p中作为P前面A的个数。

PT之间

T的索引 - P的索引再减去1.比如

PTA

012

2 - 0 - 1 = 1,1为PT间A的个数

T之后A的个数

字符串长度 - T的索引 - 1

PTAAAA

0123456

6 - 1 - 1 = 4为T之后A的个数

P和T之间必须有A

那么P和T的索引之差就不能小于1

只有P,A,T三种字符

那么m.size() == 3,如果还有多的或者是不足三种,m.size()就不为3了

m.size()代表的是这个键值对中字符种类的个数

P,T个数只有一个

那么,m['P'] == 1, m['T'] == 1

代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
    string s;
    int n = 0;
    int t = 0;
    int p = 0;
    cin >> n;
    int i = 0;
    for (i = 0; i < n; i++)
    {
        cin >> s;
        map <char, int> m;

        int j = 0;
        for (j = 0; j < s.size(); j++)
        {
            m[s[j]]++;//统计字符种类数,以及每种字符的个数
            if (s[j] == 'P')
            {
                p = j;
            }
            if (s[j] == 'T')
            {
                t = j;
            }
        }
        if (m['T'] == 1 && //T只有一个
            m['P'] == 1 && //P只有一个
            m.size() == 3&& //只有P,A,T三种字符
            t - p > 1 && //P和T之间必须有A
            m['A'] != 0 &&//A的个数不为0
            p * (t - p - 1) == s.length() - t - 1//P前的A * PT间的A == T后的A
            )
        {
            cout << "YES" << endl;
        }
        else
        {
            cout << "NO" << endl;
        }
    }
    return 0;
}

自己写的错误

将if (s[j] == 'P')写成if (m[s[j]]=='P')

分析

  1. 原意
    • 当代码为if (s[j]=='P') p = j;时,它的原意是检查字符串s中的第j个字符是否为'P'。如果是,就将j的值赋给变量p,这里p很可能是用来记录字符'P'在字符串中的位置索引。
  2. 错误写法的影响及区别
    • 当写成if (m[s[j]]=='P') p = j;时:
      • 首先,m是一个map<char, int>类型,m[s[j]]会返回一个int类型的值(这个值是字符s[j]m中的计数)。而'P'是一个字符常量。在C++ 中,将一个int类型的值与一个字符常量进行比较是类型不匹配的操作。
      • 这种错误写法会导致程序逻辑混乱。因为它不是在检查字符串中的字符是否为'P',而是在检查字符s[j]m中的计数是否等于字符'P'的ASCII码值(实际上由于类型不匹配,这种比较没有实际意义)。这与原代码的功能完全不同,原代码是在寻找字符串中'P'字符的位置,而错误写法是在对一个不相关的计数进行无意义的比较。

map<char, int> m不放入循环

分析

  1. 作用域与数据复用问题
    • 如果将map<char, int> m;放在循环外面,每次循环不会重新创建一个新的m
    • 这可能导致数据复用问题。例如,在处理多个不同的输入字符串时,m会累积之前字符串中字符的计数信息。如果第一个字符串是"PAT",处理完后m['P'] = 1m['A'] = 1m['T'] = 1。当处理下一个字符串时,m已经有了之前的计数,这会干扰对新字符串中字符的正确统计。
  2. 逻辑错误
    • 从逻辑上讲,程序可能会得到错误的结果。因为对于每个输入字符串,都应该独立地统计其中字符的出现次数。如果m在循环外,就无法保证每个字符串的统计是独立的。例如,程序可能会错误地判断字符出现的次数或者满足某些条件的情况,如判断是否只有特定的字符(PAT)以及它们的数量关系是否符合要求等都会因为m的复用而得出错误的结论。

漏写m[s[j]]++;

  1. 代码目的

    • 在这段代码中,m[s[j]]++;这行代码的目的是统计字符串中每个字符出现的次数。
    • 这里m是一个map<char, int>类型的容器,它的键是字符类型(char),值是整数类型(int)。
    • 当执行m[s[j]]++;时:
      • 如果s[j]这个字符是第一次出现在字符串中,那么m[s[j]]会创建一个新的键值对,键为s[j],值初始化为0,然后执行++操作后,这个字符对应的计数就变为1,表示这个字符出现了1次。
      • 如果s[j]这个字符已经在之前出现过,那么m[s[j]]会直接找到对应的键值对,然后执行++操作,将这个字符的计数加1,表示这个字符又出现了一次。
    • 这样做是为了后续判断字符串中是否只有PAT三种字符(通过m.size()==3判断)以及判断PAT的数量是否符合要求(例如m['P'] == 1等)。
  2. 计数功能缺失

    • 如果没有m[s[j]]++;这行代码,首先会导致字符计数功能无法实现。
    • 假设m是用于统计字符串中字符出现次数的map,原本这行代码会根据字符串中的字符s[j],在m中找到对应的键(如果不存在则创建),并将其对应的值加1。没有这行代码,就不能对字符串中的字符进行计数。
  3. 后续判断错误

    • 在程序后续可能存在对字符出现次数的判断逻辑。例如,可能需要判断某个字符是否只出现了特定的次数,或者判断不同字符出现次数之间的关系。
    • 由于没有正确统计字符出现次数,这些判断都会得出错误的结果。例如,如果需要判断字符串中是否只有特定的三种字符(如PAT)且数量关系符合某种规则,由于没有准确的计数,可能会错误地认为字符串满足或不满足条件。

代码引用

柳婼的代码

相关推荐
Eward-an8 分钟前
LeetCode 76. 最小覆盖子串(详细技术解析)
python·算法·leetcode·职场和发展
guygg8810 分钟前
基于ADMM的MRI-PET高质量图像重建算法MATLAB实现
开发语言·算法·matlab
李昊哲小课13 分钟前
Python itertools模块详细教程
数据结构·python·散列表
moonlight030413 分钟前
类加载子系统
java·jvm·算法
baivfhpwxf202319 分钟前
ACS X轴回零程序 项目实战版
网络·数据库·算法
盐水冰28 分钟前
【Redis】学习(2)Redis常见命令
数据库·redis·学习
一叶落43833 分钟前
LeetCode 219. 存在重复元素 II(C语言详解)
算法·哈希算法·散列表
adore.96834 分钟前
3.13 复试学习
学习
像污秽一样35 分钟前
算法设计与分析-习题2.4
数据结构·算法·排序算法
不想看见40436 分钟前
Reverse Bits位运算基础问题--力扣101算法题解笔记
笔记·算法·leetcode