表达式:向量下标超出排名系统范围

问题描述 投票:0回答:1

我正在开发一个模仿荣誉的项目,员工在满足一些要求后就会得到晋升。问题是我收到一条错误消息“表达式:向量下标超出范围”,据我了解“合格候选人的索引与要从中选择该候选人的办公室不匹配”。有时它工作没有问题。

当我检查下面给出的 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);
    }
  }
}

我要么无知,要么太累,不知道如何修复。请帮忙

c++ vector indexing
1个回答
0
投票

代码中的核心问题是从原始数组中删除合适的候选者不会更改所有剩余合适候选者的索引。这可能导致该向量的后面元素指向空白空间。

您可以通过首先提取符合条件的代表,将人员从符合条件的池中提拔出来,然后返还剩下的人,从结构上防止这种情况发生。

首先,一些与代表移动过程无关的辅助函数:

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));

一些技巧:

  1. <algorithm>
    中的多个函数将 for 循环替换为具有明确范围的单个函数调用。
  2. Representative & chosenRep = *it
    周围的内部块限制了该变量的生命周期,并防止您在提升后意外使用代表。
  3. index
    转换为
    enum
    来描述它是什么样的代表。
© www.soinside.com 2019 - 2024. All rights reserved.