我正在开发一个模仿荣誉的项目,员工在满足一些要求后就会得到晋升。问题是我收到一条错误消息“表达式:向量下标超出范围”,据我了解“合格候选人的索引与要从中选择该候选人的办公室不匹配”。有时它工作没有问题。
当我检查下面给出的 while 循环时,我意识到 selectedIndex 超出了 Government[index - 1].representatives 的范围。
if (openSeats > 0) {
// Get the office one rank below
// PoliticalOffice& previousOffice = government[index - 1];
std::vector<int> suitableCandidatesIndices;
if (government[index - 1].representatives.size() > 0) {
for (int candidateIndex = 0; candidateIndex < government[index - 1].representatives.size(); ++candidateIndex) {
// Check if the representative meets the eligibility criteria
if ((index == 1 && government[index - 1].representatives[candidateIndex].entry &&
government[index - 1].representatives[candidateIndex].age >= 32 &&
government[index - 1].representatives[candidateIndex].yearsInServiceAsEntry >= 2) ||
(index == 2 && government[index - 1].representatives[candidateIndex].mid &&
government[index - 1].representatives[candidateIndex].age >= 35 &&
government[index - 1].representatives[candidateIndex].yearsInServiceAsMid >= 2) ||
(index == 3 && government[index - 1].representatives[candidateIndex].senior &&
government[index - 1].representatives[candidateIndex].age >= 46 &&
government[index - 1].representatives[candidateIndex].yearsInServiceAsSenior >= 2)) {
suitableCandidatesIndices.push_back(candidateIndex);
}
}
}
while (!suitableCandidatesIndices.empty() && openSeats > 0) {
// Randomly select a representative from the pool of suitable candidates
std::uniform_int_distribution<int> distribution(
0, suitableCandidatesIndices.size() - 1);
int chosenIndex = suitableCandidatesIndices[distribution(generator)];
Representative& chosenRep = government[index - 1].representatives[chosenIndex];
// Assign the chosen representative to the current position
switch (index) {
case 1: // Mid-level
chosenRep.mid = true;
chosenRep.entry = false; // No longer an Entry-level
chosenRep.yearsInServiceAsMid = 0;
break;
case 2: // Senior
chosenRep.senior = true;
chosenRep.mid = false; // No longer a Mid-level
chosenRep.yearsInServiceAsSenior = 0;
break;
case 3: // Executive
chosenRep.executive = true;
chosenRep.firstTermYear =
currentYear; // Record the year of first term as Executive
chosenRep.senior = false; // No longer a Senior
break;
}
office.representatives.push_back(chosenRep);
filledSeats++;
// Remove the selected representative from the lower-ranking office
government[index - 1].representatives.erase(government[index - 1].representatives.begin() +
chosenIndex);
// Decrease the count of open seats
--openSeats;
int indexToRemove = chosenIndex;
auto iterator = find(suitableCandidatesIndices.begin(),
suitableCandidatesIndices.end(), indexToRemove);
// Update the list of suitable candidates
if (iterator != suitableCandidatesIndices.end()) {
suitableCandidatesIndices.erase(iterator);
}
}
}
我要么无知,要么太累,不知道如何修复。请帮忙
代码中的核心问题是从原始数组中删除合适的候选者不会更改所有剩余合适候选者的索引。这可能导致该向量的后面元素指向空白空间。
您可以通过首先提取符合条件的代表,将人员从符合条件的池中提拔出来,然后返还剩下的人,从结构上防止这种情况发生。
首先,一些与代表移动过程无关的辅助函数:
enum Level { Entry, Mid, Senior, Executive };
bool isEligible(const Level target, const Representative& r) {
switch (target) {
case Mid: return r.entry && r.age >= 32 && r.yearsInServiceAsEntry >= 2;
case Senior: return r.mid && r.age >= 35 && r.yearsInServiceAsMid >= 2;
case Executive: return r.senior && r.age >= 46 && r.yearsInServiceAsSenior >= 2;
default: return false; /* unreachable */
}
}
void promote(const Level l, Representative r) {
// Assign the chosen representative to the current position
switch (l) {
case Mid:
chosenRep.mid = true;
chosenRep.entry = false; // No longer an Entry-level
chosenRep.yearsInServiceAsMid = 0;
break;
case Senior:
chosenRep.senior = true;
chosenRep.mid = false; // No longer a Mid-level
chosenRep.yearsInServiceAsSenior = 0;
break;
case Executive:
chosenRep.executive = true;
chosenRep.senior = false; // No longer a Senior
chosenRep.firstTermYear = currentYear; // Record the year of first term as Executive
break;
}
}
促销函数的主体变为:
if (!openSeats) {
return;
}
// Get the office one rank below
PoliticalOffice& previousOffice = government[index - 1];
std::vector<Representative> eligible;
std::remove_copy_if(
previousOffice.representatives.begin(),
previousOffice.representatives.end(),
std::back_inserter(eligible),
[](const Representative& r) { return isEligible(index, l); });
while (!eligible.empty() && openSeats > 0) {
auto it = eligible.begin() + std::uniform_int_distribution{0, eligible.size() - 1}(generator);
{
Representative& chosenRep = *it;
promote(index, chosenRep);
office.representatives.push_back(chosenRep);
filledSeats++;
}
eligible.erase(it);
// Decrease the count of open seats
--openSeats;
}
// Return remaining representatives to the previous office
std::copy(eligible.begin(), eligible.end(), std::back_inserter(previousOffice.representatives));
一些技巧:
<algorithm>
中的多个函数将 for 循环替换为具有明确范围的单个函数调用。Representative & chosenRep = *it
周围的内部块限制了该变量的生命周期,并防止您在提升后意外使用代表。index
转换为 enum
来描述它是什么样的代表。