1 条题解

  • 0
    @ 2026-1-30 10:03:45

    根据题目描述,我们需要:

    • 输入一个包含 * 的字符串。
    • 保留字符串开头和结尾的 *,但删除中间的 *
    • 输出处理后的字符串。

    ✅ 示例分析

    输入:
    ***ABC123**123*abc************

    输出:
    ***ABC123123abc************

    说明:

    • 开头的 *** 保留;
    • 中间的 *** 被删除;
    • 结尾的 ************ 保留;
    • 所以只保留首尾的 *,中间的 * 都删掉。

    ✅ 解题思路

    我们可以:

    1. 找到第一个非 * 字符的位置(即前导 * 的结束)。
    2. 找到最后一个非 * 字符的位置(即尾随 * 的开始)。
    3. 把字符串分为三部分:
      • 前导 *
      • 中间非 * 的部分(不包括中间的 *
      • 尾随 *
    4. 拼接这三部分。

    或者更简单的方法是:

    • 从左往右遍历,直到遇到第一个非 *,记录前缀;
    • 从右往左遍历,直到遇到第一个非 *,记录后缀;
    • 中间部分只保留非 * 的字符。

    但注意:我们不需要保留中间的 *,只要把所有 * 当作“分隔符”,只保留首尾的 * 即可。

    更简单的理解是:只保留最前面连续的 * 和最后面连续的 *,中间的 * 全部删除。


    ✅ C++ 实现代码

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string s;
        getline(cin, s);
    
        int n = s.length();
    
        // 找到第一个不是 '*' 的位置(前导 * 的结尾)
        int start = 0;
        while (start < n && s[start] == '*') {
            start++;
        }
    
        // 找到最后一个不是 '*' 的位置(尾随 * 的开始)
        int end = n - 1;
        while (end >= 0 && s[end] == '*') {
            end--;
        }
    
        // 构造结果
        string result = "";
    
        // 添加前导 *
        for (int i = 0; i < start; i++) {
            result += '*';
        }
    
        // 添加中间非 * 的部分(注意:中间的 * 不加)
        for (int i = start; i <= end; i++) {
            if (s[i] != '*') {
                result += s[i];
            }
        }
    
        // 添加尾随 *
        for (int i = end + 1; i < n; i++) {
            result += '*';
        }
    
        cout << result << endl;
    
        return 0;
    }
    

    ✅ 测试样例

    输入:

    ***ABC123**123*abc************
    

    输出:

    ***ABC123123abc************
    

    ✅ 算法复杂度

    • 时间:O(n)
    • 空间:O(n)(用于存储结果)

    ✅ 注意事项

    • 使用 getline(cin, s) 读取整行,防止空格或换行问题。
    • 处理边界情况(如全为 *、无 * 等)该代码也适用。

    如果你希望代码更简洁,也可以这样写(使用 find_first_not_offind_last_not_of):

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string s;
        getline(cin, s);
    
        size_t first_non_star = s.find_first_not_of('*');
        size_t last_non_star = s.find_last_not_of('*');
    
        string prefix = s.substr(0, first_non_star);
        string suffix = s.substr(last_non_star + 1);
    
        string middle;
        for (size_t i = first_non_star; i <= last_non_star; ++i) {
            if (s[i] != '*') {
                middle += s[i];
            }
        }
    
        cout << prefix << middle << suffix << endl;
    
        return 0;
    }
    

    两种方式都可以,推荐第二种更简洁清晰。

    • 1

    信息

    ID
    584
    时间
    1000ms
    内存
    32MiB
    难度
    10
    标签
    递交数
    6
    已通过
    1
    上传者