GESP2026‑9 三级真题编程题2:分割字符串 | string find、erase、substr 应用

四季读书网 4 0
GESP2026‑9 三级真题编程题2:分割字符串 | string find、erase、substr 应用

GESP 2026年9月份三级真题

3.2 编程题2: 分割字符串

时间限制:1.0 s

内存限制:512.0 MB

3.2.1 题目描述

小明拿到了一段字符串文本,小明希望用下面的规则分割这个字符串:

  1. 小明从左到右扫描字符串,遇到第一个空格后停止,并将字符串分割为左右两个部分(舍弃用于分割的这个空格);
  2. 对于上次分割后右侧的字符串,小明继续扫描,第一次遇到连续两个空格后停止,并将字符串分割为左右两个部分(舍弃用于分割的这两个空格);
  3. 对于上次分割后右侧的字符串,小明继续扫描,第一次遇到连续三个空格后停止,并将字符串分割为左右两个部分(舍弃用于分割的这三个空格);
  4. 以此类推,小明每分割一次,下一次分割就需要更长的连续空格;直到字符串无法再次分割。

最后输出每次分割的左侧的字符串,以及最后一次分割的右侧字符串。 如果字符串完全无法进行任何一次分割,直接输出其本身。

3.2.2 输入格式

输入一行,一个字符串。

3.2.3 输出格式

输出若干行。每行为分割后的一个字符串,注意依次输出: 第一次分割左侧的字符串,第二次分割左侧的字符串,…,最后一次分割左侧的字符串,最后一次分割右侧的字符串。

3.2.4 样例

3.2.5 输入样例1

sdfd 55 55   99312

3.2.6 输出样例1

sdfd55 55 99312

3.2.7 样例解释1

  1. 第一次分割将字符串分割为 sdfd 和 55 55   99312;
  2. 第二次分割将字符串分割为 55 55 和  99312。

对于第二次分割,注意 55 和 55 之间虽然有空格,但是第二次分割需要连续两个空格; 另外,55 55 和 99312 之间有三个空格,第二次分割只需要两个,所以会分割为55 55和 99312,也就是右侧会留下一个空格;因为只留下了一个空格,所以不再满足第三次分割要求。

3.2.8 输入样例2

AbCd   999

3.2.9 输出样例2

AbCd999

3.2.10 样例解释2

  1. 第一次分割将字符串分割为 AbCd 和   999;
  2. 第二次分割将字符串分割为空字符串和 999。

由于AbCd和999之间有三个空格,第一次分割消耗掉一个,还剩下两个空格,因此还可以进行第二次分割。这个时候分割出来的左侧是空字符串,因此输出中会输出一个空行,这个空行不能省略。

3.2.11 数据范围

字符串长度不超过1000,字符串中只包含大写字母、小写字母、数字,或空格,且输入字符串不会以空格结尾。

特别强调:输入仅一行,但可能包含若干空格。


题解思路

一、题目核心规则

分割规则是逐次递增空格数量:

  • 第 1 轮:找 1 个连续空格 分割
  • 第 2 轮:找 2 个连续空格 分割
  • 第 3 轮:找 3 个连续空格 分割
  • ……以此类推 每一轮分割:输出左边内容,舍弃分割用的空格,用右边剩余内容继续分割;直到当前轮数要求的连续空格找不到为止,最后输出剩余内容。

二、整体解题思路

本题不需要复杂字符串拆分,核心技巧:动态生成 k 个空格 + find 查找分割点。 整体流程:

  1. 读取整行带空格字符串
  2. 从 k=1 开始循环,每次轮次 k 自增
  3. 每一轮生成 k 个连续空格 作为分割标记
  4. 在当前字符串中查找这一段空格:
  • 找到:输出左边内容,删除左边内容 + 分割空格,剩余部分进入下一轮
  • 找不到:直接输出剩余内容,程序结束

三、参考题解

#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;}

四、关键考点&代码说明

  1. getline(cin,s):必须用整行读入,题目输入带有空格,cin >> s遇到空格就截断,会出错。
  2. sp += " ":循环k次,sp就得到k个连续空格,匹配题目规则:第k次分割找k个空格。
  3. s.find(sp):查找k个连续空格;返回string::npos代表找不到,直接输出剩余字符串结束程序。
  4. s.substr(0,p):取出分割点左边的字符串并打印。
  5. s.erase(0,p+k):
    • p:左边字符串的字符个数
    • k:本次分割舍弃的空格数量
    • 删除之后s就变成分割后的右侧子串,进入下一轮循环。
  6. 无限for(int k=1;;k++):k自动递增,每次分割空格数量+1;靠break跳出循环。

抱歉,评论功能暂时关闭!