c++ erase 中的坑

C/C++字符串删除元素异常处理
博客讲述了一段C/C++代码,最初正常运行,修改为依次删除字符串元素时出错并返回异常。经查阅资料,得知erase返回值为被删除迭代器的下一个迭代器,修改程序后无异常。

 

先看一段正常的代码

#include <iostream> 
#include <string> 
using namespace std; 
 
int main() { 
 
    string str = "123456789"; 
    str.erase(str.begin() + 2, str.end() - 2); 
    cout << str; 

    return 0;
}

移除中间的一段字符

很好的发挥了作用

然后改了一下 希望依次删除字符串中的元素

    string::iterator it; 
    // 错误写法 
    for (it = str.begin(); it != str.end(); it++) 
    { 
        cout << *it << " str: " << str << endl; 
        str.erase(it); 
    }

 

结果出错并且返回异常

查资料得知erase的返回值为被删除迭代器的下一个迭代器

修改程序

 

   // 正确写法
    for (it = str.begin(); it != str.end(); )   // 注意这里去掉了it++
    {
        cout << *it << " str: " << str << endl;
        it = str.erase(it);

    }

 

 结果无异常

转载于:https://www.cnblogs.com/bugcreator/p/11178490.html

<think>好的,用户之前让我解释了一段C++的two sum代码,其中用到了unordered_map,也就是哈希表。现在用户问的是“C++中哈希表是什么,怎么使用,我没学过C++”。看起来用户是刚接触C++,可能对哈希表的概念和使用不太清楚,需要从基础讲起。 首先,用户没学过C++,所以需要避免使用太多专业术语,用简单的语言解释。哈希表在C++中的实现主要是unordered_map和unordered_set,这里用户可能关心的是如何用它来存储和查找数据,比如在two sum问题中的应用。 接下来,用户可能想知道哈希表的基本操作,比如插入、查找、删除,以及它们的语法。需要举例说明,这样用户更容易理解。同时,要对比C语言的情况,因为用户之前的问题中提到了C语言的对比,可能用户有C的基础,想通过对比来理解C++的不同之处。 另外,用户可能想知道哈希表的原理,比如为什么查找速度快,时间复杂度是怎样的。这时候需要简单解释哈希函数和冲突解决,但不要过于深入,避免让用户感到困惑。 还要注意用户的实际应用场景,比如在算法题中的使用,所以可以举一些常见的例子,比如统计频率、去重等,这样用户能更好地联想到如何应用哈希表解决问题。 最后,确保回答结构清晰,分点讲解,步骤明确,帮助用户逐步建立对哈希表的理解。同时提醒用户在使用时要注意键的唯一性、冲突处理以及内存管理的问题,这些都是新手容易遇到的。</think>好的!我将用通俗易懂的方式为你解释C++中的哈希表(HashMap),即使你完全没有C++基础,也能轻松理解。 --- ### 一、哈希表是什么? 哈希表(Hash Table)就像一个**智能快递柜**: - **核心功能**:能通过**钥匙(Key)**快速找到对应的**包裹(Value)** - **特点**: - 查找速度极快(平均$O(1)$时间复杂度) - 存储键值对(如:姓名→电话号码) - 自动管理存储位置(开发者不用关心数据存在哪) --- ### 二、C++中的哈希表怎么用? C++标准库提供了`unordered_map`来实现哈希表,使用分三步: #### 1. 包含头文件 ```cpp #include <unordered_map> // 就像拿快递前要先找到快递柜 ``` #### 2. 创建哈希表 ```cpp // 创建存放<string, int>类型键值对的哈希表 // 格式:unordered_map<键类型, 值类型> 表名; unordered_map<string, int> ageDB; // 建立姓名→年龄的映射 ``` #### 3. 基本操作 | 操作 | 代码示例 | 类比说明 | |-------------------|----------------------------|----------------------------| | **插入数据** | `ageDB["Alice"] = 25;` | 把Alice的包裹25存到对应格子 | | **查找数据** | `ageDB.find("Bob")` | 用名字找对应的格子 | | **检查存在性** | `ageDB.count("Charlie")` | 查看是否有这个人的记录 | | **删除数据** | `ageDB.erase("David")` | 把David的记录取出快递柜 | | **遍历所有数据** | `for(auto& pair : ageDB){...}` | 逐个检查所有快递格 | --- ### 三、具体使用示例 ```cpp #include <iostream> #include <unordered_map> using namespace std; int main() { // 创建哈希表(姓名→成绩) unordered_map<string, double> scoreDB; // 插入数据 scoreDB["小明"] = 92.5; scoreDB["小红"] = 88.0; scoreDB.insert({"小刚", 76.5}); // 另一种插入方式 // 查找数据 if(scoreDB.find("小红") != scoreDB.end()) { cout << "小红的成绩:" << scoreDB["小红"] << endl; } // 删除数据 scoreDB.erase("小刚"); // 遍历所有数据 for(auto& entry : scoreDB) { // entry是键值对 cout << entry.first << "的成绩是" << entry.second << endl; } return 0; } ``` --- ### 四、对比C语言实现 如果你学过C语言,可以这样对比理解: | 功能 | C++实现 | C语言近似实现 | |-------------------|--------------------------|----------------------------| | 哈希表 | `unordered_map` | 结构体数组+手动哈希函数 | | 插入元素 | `map[key] = value` | 遍历数组找空位 | | 查找元素 | `map.find(key)` | 遍历数组逐个比较 | | 删除元素 | `map.erase(key)` | 标记删除或移动元素 | | 自动扩容 | 自动处理 | 需手动realloc | | 时间复杂度 | 查找/插入平均O(1) | 通常O(n) | --- ### 五、为什么用哈希表? 通过实际场景理解优势: ```cpp // 场景:统计单词出现次数 vector<string> words = {"apple", "banana", "apple", "orange"}; // 传统方法(类似C语言实现) vector<pair<string, int>> counts; // 需要遍历查找 for(auto& word : words){ bool found = false; for(auto& p : counts){ if(p.first == word){ p.second++; found = true; break; } } if(!found) counts.push_back({word,1}); } // 哈希表方法 unordered_map<string, int> wordCount; for(auto& word : words){ wordCount[word]++; // 自动处理存在性检查 } ``` --- ### 六、注意事项 1. **键唯一性**:每个键只能出现一次(如不能有两个"小明") 2. **哈希冲突**:当不同键产生相同哈希值时,内部会自动处理 3. **无序性**:遍历时元素的顺序是随机的(若需要有序应使用`map`) 4. **内存消耗**:比数组占用更多内存,但换取快速访问 --- 现在你对C++的哈希表应该有了基本认识!如果需要进一步了解具体操作或实际应用场景,可以告诉我你想了解的方面~ 😊
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值