GESP 2026年9月份三级真题
3.2 编程题2: 分割字符串
时间限制:1.0 s
内存限制:512.0 MB
3.2.1 题目描述
小明拿到了一段字符串文本,小明希望用下面的规则分割这个字符串:
小明从左到右扫描字符串,遇到第一个空格后停止,并将字符串分割为左右两个部分(舍弃用于分割的这个空格); 对于上次分割后右侧的字符串,小明继续扫描,第一次遇到连续两个空格后停止,并将字符串分割为左右两个部分(舍弃用于分割的这两个空格); 对于上次分割后右侧的字符串,小明继续扫描,第一次遇到连续三个空格后停止,并将字符串分割为左右两个部分(舍弃用于分割的这三个空格); 以此类推,小明每分割一次,下一次分割就需要更长的连续空格;直到字符串无法再次分割。
最后输出每次分割的左侧的字符串,以及最后一次分割的右侧字符串。 如果字符串完全无法进行任何一次分割,直接输出其本身。
3.2.2 输入格式
输入一行,一个字符串。
3.2.3 输出格式
输出若干行。每行为分割后的一个字符串,注意依次输出: 第一次分割左侧的字符串,第二次分割左侧的字符串,…,最后一次分割左侧的字符串,最后一次分割右侧的字符串。
3.2.4 样例
3.2.5 输入样例1
sdfd 55 55 993123.2.6 输出样例1
sdfd55 55 993123.2.7 样例解释1
第一次分割将字符串分割为 sdfd和55 55 99312;第二次分割将字符串分割为 55 55和99312。
对于第二次分割,注意 55 和 55 之间虽然有空格,但是第二次分割需要连续两个空格; 另外,55 55 和 99312 之间有三个空格,第二次分割只需要两个,所以会分割为55 55和 99312,也就是右侧会留下一个空格;因为只留下了一个空格,所以不再满足第三次分割要求。
3.2.8 输入样例2
AbCd 9993.2.9 输出样例2
AbCd9993.2.10 样例解释2
第一次分割将字符串分割为 AbCd和999;第二次分割将字符串分割为空字符串和 999。
由于AbCd和999之间有三个空格,第一次分割消耗掉一个,还剩下两个空格,因此还可以进行第二次分割。这个时候分割出来的左侧是空字符串,因此输出中会输出一个空行,这个空行不能省略。
3.2.11 数据范围
字符串长度不超过1000,字符串中只包含大写字母、小写字母、数字,或空格,且输入字符串不会以空格结尾。
特别强调:输入仅一行,但可能包含若干空格。
题解思路
一、题目核心规则
分割规则是逐次递增空格数量:
第 1 轮:找 1 个连续空格 分割 第 2 轮:找 2 个连续空格 分割 第 3 轮:找 3 个连续空格 分割 ……以此类推 每一轮分割:输出左边内容,舍弃分割用的空格,用右边剩余内容继续分割;直到当前轮数要求的连续空格找不到为止,最后输出剩余内容。
二、整体解题思路
本题不需要复杂字符串拆分,核心技巧:动态生成 k 个空格 + find 查找分割点。 整体流程:
读取整行带空格字符串 从 k=1 开始循环,每次轮次 k 自增 每一轮生成 k 个连续空格 作为分割标记 在当前字符串中查找这一段空格:
找到:输出左边内容,删除左边内容 + 分割空格,剩余部分进入下一轮 找不到:直接输出剩余内容,程序结束
三、参考题解
#include<bits/stdc++.h>usingnamespace std;intmain(){ string s,sp; // s保存当前待分割字符串;sp用来生成k个连续空格的分割标记 getline(cin,s); // 读取整行输入,包含空格,不能用cin>>s size_t p; // 保存find查找返回的下标,必须使用size_t类型 // k代表本次分割需要的连续空格数量:第1次k=1,第2次k=2,第3次k=3…… for(int k=1;;k++){ sp += " "; // 每次循环往sp追加1个空格,sp变成k个连续空格 p = s.find(sp); // 在当前字符串s中查找k个连续空格 // 找不到k个连续空格,无法继续分割,直接输出剩余字符串,结束循环 if(p==string::npos){cout<<s<<endl;break; }else{// 截取从0开始、长度p的子串,也就是本次分割的左侧部分,输出cout<<s.substr(0,p)<<endl;// 删除:从下标0开始,删除 p + k 个字符// p是左侧内容长度,k是分割用的空格数量,把左侧内容+分割空格全部删掉 s.erase(0,p+k); } } return 0;}四、关键考点&代码说明
getline(cin,s):必须用整行读入,题目输入带有空格,cin >> s遇到空格就截断,会出错。sp += " ":循环k次,sp就得到k个连续空格,匹配题目规则:第k次分割找k个空格。s.find(sp):查找k个连续空格;返回string::npos代表找不到,直接输出剩余字符串结束程序。s.substr(0,p):取出分割点左边的字符串并打印。s.erase(0,p+k):p:左边字符串的字符个数k:本次分割舍弃的空格数量删除之后 s就变成分割后的右侧子串,进入下一轮循环。无限 for(int k=1;;k++):k自动递增,每次分割空格数量+1;靠break跳出循环。