员工晋升系统出现vector下标越界问题,求修复方案
修复"vector subscript out of range"错误:员工晋升系统索引不匹配问题
问题根源
你遇到的偶发下标越界,本质是候选索引与原候选池的实时状态不一致:
- 初始时
suitableCandidatesIndices存储的是government[index-1].representatives的有效下标 - 当调用
erase删除原候选池中的元素后,原池内后续元素的下标会自动前移一位,但suitableCandidatesIndices中存储的旧索引并未同步更新 - 后续随机选中的旧索引如果大于当前原池的最大有效下标,就会触发越界错误
比如原池有5个元素(下标0-4),suitableCandidatesIndices存了[2,3,4];删除下标2的元素后,原池剩下的元素下标变为0-3,但suitableCandidatesIndices里的3、4仍保留,此时访问下标4就会超出范围。
修复方案
方案1:同步更新候选索引(最小改动原代码)
在删除原池元素后,遍历suitableCandidatesIndices,将所有大于被删索引的值减1,保证索引与原池实时状态匹配:
修改原代码中删除候选后的更新逻辑:
// 移除当前选中的索引 auto iterator = find(suitableCandidatesIndices.begin(), suitableCandidatesIndices.end(), chosenIndex); if (iterator != suitableCandidatesIndices.end()) { suitableCandidatesIndices.erase(iterator); } // 关键:同步更新所有大于被删索引的候选索引 for (auto& idx : suitableCandidatesIndices) { if (idx > chosenIndex) { idx--; } }
方案2:改用对象指针存储候选(更可靠,避免索引维护)
放弃存储索引,直接存储符合条件的Representative对象指针,彻底规避索引不匹配问题:
- 修改候选列表的类型:
// 替换原std::vector<int> suitableCandidatesIndices; std::vector<Representative*> suitableCandidates;
- 筛选候选时存储指针:
if (government[index - 1].representatives.size() > 0) { for (auto& rep : government[index - 1].representatives) { // 检查 eligibility criteria if ((index == 1 && rep.entry && rep.age >= 32 && rep.yearsInServiceAsEntry >= 2) || (index == 2 && rep.mid && rep.age >= 35 && rep.yearsInServiceAsMid >= 2) || (index == 3 && rep.senior && rep.age >= 46 && rep.yearsInServiceAsSenior >= 2)) { suitableCandidates.push_back(&rep); } } }
- 修改while循环内的逻辑:
while (!suitableCandidates.empty() && openSeats > 0) { std::uniform_int_distribution<int> distribution(0, suitableCandidates.size() - 1); int chosenPos = distribution(generator); Representative* chosenRepPtr = suitableCandidates[chosenPos]; // 更新晋升状态 switch (index) { case 1: // Mid-level chosenRepPtr->mid = true; chosenRepPtr->entry = false; chosenRepPtr->yearsInServiceAsMid = 0; break; case 2: // Senior chosenRepPtr->senior = true; chosenRepPtr->mid = false; chosenRepPtr->yearsInServiceAsSenior = 0; break; case 3: // Executive chosenRepPtr->executive = true; chosenRepPtr->firstTermYear = currentYear; chosenRepPtr->senior = false; break; } office.representatives.push_back(*chosenRepPtr); filledSeats++; // 从原部门移除该员工 auto& prevOfficeReps = government[index - 1].representatives; auto it = std::find(prevOfficeReps.begin(), prevOfficeReps.end(), *chosenRepPtr); if (it != prevOfficeReps.end()) { prevOfficeReps.erase(it); } --openSeats; // 从候选列表移除该指针 suitableCandidates.erase(suitableCandidates.begin() + chosenPos); }
内容的提问来源于stack exchange,提问作者SerkanB
相关产品推荐
相关产品推荐

