当前位置: 首页 > news >正文

【算法】 【c++】字符串s1 中删除所有 s2 中出现的字符

【算法】 【c++】字符串s1 中删除所有 s2 中出现的字符

eg:
s1:“helloworld”
s2:“wd”
删除后:s1:“helloorl”

1 双循环匹配并删除–>时间复杂度O(n^2)

string 里面的删除函数–>erase

std::string::erase` 是 C++ 标准库中用于删除字符串中字符或子串的方法。


1. erase(pos, len)
  • 作用:从字符串的 索引 pos 位置开始,删除 len 个字符。
  • 参数
    • pos:起始索引(从 0 开始)。
    • len:要删除的字符数量(默认值 std::string::npos,即删除到末尾)。
  • 返回值:修改后的 string 自身(左移剩余字符)。

示例

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s = "abcdef";

    s.erase(2, 2);  // 从索引 2 ('c') 开始删除 2 个字符,变成 "abef"

    cout << s << endl;  // 输出: "abef"
    return 0;
}

2. erase(iterator pos)
  • 作用:删除 pos 迭代器指向的字符。
  • 参数
    • pos:指向要删除字符的 迭代器
  • 返回值:指向删除字符后 下一个字符的迭代器

示例

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s = "abcdef";

    auto it = s.begin() + 2;  // 指向 'c'
    s.erase(it);  // 删除 'c',变成 "abdef"

    cout << s << endl;  // 输出: "abdef"
    return 0;
}

3. erase(iterator first, iterator last)
  • 作用:删除 [first, last) 范围内的字符(包括 first,不包括 last)。
  • 参数
    • first:起始迭代器。
    • last:结束迭代器(不删除)。
  • 返回值:指向删除区域后第一个剩余字符的迭代器。

示例

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s = "abcdef";

    s.erase(s.begin() + 1, s.begin() + 4);  // 删除索引 1~3 ('b' 到 'd'),变成 "aef"

    cout << s << endl;  // 输出: "aef"
    return 0;
}

4. erase-remove惯用法(高效删除多个字符)

在 C++ 里,erase 不能直接删除多个 指定字符,但可以配合 std::remove_if 实现 高效批量删除

示例

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    string s = "abcdebc";

    // 删除所有 'b'
    s.erase(remove(s.begin(), s.end(), 'b'), s.end());

    cout << s << endl;  // 输出: "acdec"
    return 0;
}

原理

  1. remove 把所有 非 ‘b’ 的字符 重新排列到前面,返回新末尾的迭代器。
  2. erase 删除新末尾之后的所有字符,完成去重。

总结

用法作用适用场景
erase(pos, len)pos 开始删除 len 个字符删除固定范围的子串
erase(iterator pos)删除 pos 迭代器指向的字符通过迭代器删除单个字符
erase(iterator first, iterator last)删除 [first, last) 范围字符通过迭代器删除一段子串
erase(remove_if(...))批量删除多个指定字符需要高效删除多个字符

#include<iostream>
using namespace std;
#include<string>
#include<vector>
void dele(string& s1, string& s2)
{
    int n2 = s2.size();
    if (n2 < 1)return;

    for (int i = 0;i < s1.size();i++)
    {
        for (int j = 0;j < n2;j++)
        {
            if (s1[i] == s2[j])
            {
                s1.erase(i,1);
                i--;
            }
        }
    }
    
}
int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    dele(s1, s2);
    cout << s1 << endl;
}

2unordered_set存储s2

unordered_set使用

是 C++ STL 提供的 无序集合,底层使用 哈希表 实现,支持 O(1) 平均时间复杂度 进行 插入、删除、查找

1. 基本用法

(1) 头文件

#include <unordered_set>

(2) 声明

unordered_set<int> mySet;  // 存储 int 类型
unordered_set<string> mySet2;  // 存储 string 类型

(3) 插入

mySet.insert(10);
mySet.insert(20);

(4) 遍历

for (int num : mySet) {  
    cout << num << " ";  
}

⚠️ 注意: unordered_set 无序存储,遍历顺序 不确定


2. 主要操作

(1) 插入元素

unordered_set<int> mySet;
mySet.insert(1);
mySet.insert(2);

(2) 查找元素

if (mySet.find(2) != mySet.end()) {  
    cout << "2 存在" << endl;  
} else {  
    cout << "2 不存在" << endl;  
}

find(x) != end() 表示 找到 x,否则 未找到

(3) 删除元素

mySet.erase(2);  // 删除值为 2 的元素

(4) 统计个数

cout << mySet.size() << endl;

(5) 清空集合

mySet.clear();

3. 高级用法

(1) 使用 count(x) 判断是否存在

if (mySet.count(2)) {
    cout << "2 存在" << endl;
} else {
    cout << "2 不存在" << endl;
}

count(x) 返回 0(不存在)或 1(存在)。

(2) 迭代器遍历

for (auto it = mySet.begin(); it != mySet.end(); ++it) {
    cout << *it << " ";
}

4. 时间复杂度

操作平均时间复杂度
insert(x)O(1)
find(x)O(1)
erase(x)O(1)
遍历O(n)

5. 适用场景
快速去重unordered_set 可以存储唯一值,O(1) 查找是否存在
快速查找:比 vectorset 更快的 O(1) 查找
集合操作:常用于 字符删除、重复元素去除 等。


  • 使用 unordered_set 来加速字符匹配,使得删除操作的时间复杂度从优化到 O(n)。
  • set的查询速度为O(1)
  • 使用writeIndex保存s1要写入的位置
  • 在存储s2的set里面查询,是否存在对应字符,不存在的写入s1前面
  • 删掉后续字符
#include <iostream>
#include <string>
#include <unordered_set>

using namespace std;

void dele(string& s1, const string& s2) {
    unordered_set<char> removeSet(s2.begin(), s2.end()); // Step 1: 用哈希表存储 s2 中所有字符
    int writeIndex = 0; // Step 2: 记录写入位置

    for (int i = 0; i < s1.size(); i++) { // Step 3: 遍历 s1
        if (!removeSet.count(s1[i])) { // Step 4: 如果 s1[i] 不在 s2 中
            s1[writeIndex++] = s1[i]; // Step 5: 把 s1[i] 写入当前位置
        }
    }
    
    s1.erase(writeIndex); // Step 6: 删除剩余部分
}

int main() {
    string s1, s2;
    cin >> s1 >> s2;

    dele(s1, s2);  // 调用删除函数
    cout << s1 << endl;  // 输出修改后的 s1

    return 0;
}

相关文章:

  • 总结 HTTP 协议的基本格式, 相关知识以及抓包工具fiddler的使用
  • 67.Harmonyos NEXT 图片预览组件之性能优化策略
  • 【Scala】
  • 论文分享 | HE-Nav: 一种适用于复杂环境中空地机器人的高性能高效导航系统
  • TIA博途在编译 PLC时出现崩溃的解决方法
  • 测不准关系
  • 【redis】zset 类型:基本命令(上)
  • Java中架构DDD:理解聚合、实体和值对象三种核心构造块
  • C#+EF+SqlServer性能优化笔记
  • Python 科学计算与机器学习入门:NumPy + Scikit-Learn 实战指南
  • 大数据-spark3.5安装部署之local模式
  • ubuntu24.04-qt5-mysql8.0
  • 【网工第6版】第1章 计算机网络概论
  • mac安装navicat及使用
  • CentOS 7 系统上安装 SQLite
  • LDR6500在Type-C转DP视频双向互传方案
  • RAW图与BAYER图异同
  • LinuX---Shell---read命令
  • 02 windows qt配置ffmpeg开发环境搭建
  • Leetcode3340:检查平衡字符串
  • 广西鹿寨一水文站“倒刺扶手”存安全隐患,官方通报处理情况
  • 国际金价下跌,中概股多数上涨,穆迪下调美国主权信用评级
  • 竞彩湃|欧联杯决赛前,曼联、热刺继续划水?
  • 阿里上财年营收增6%,蒋凡:会积极投资,把更多淘宝用户转变成即时零售用户
  • 在本轮印巴冲突的舆论场上也胜印度一筹,巴基斯坦靠什么?
  • 上海高院与上海妇联签协议,建立反家暴常态化联动协作机制