【问题标题】:Remove the first smallest number in a vector in C++ (and keep the order)在 C++ 中删除向量中的第一个最小数字(并保持顺序)
【发布时间】:2019-11-02 06:17:43
【问题描述】:

我有一个包含{1, 0, 0, 0, 0, 0 ,0}vector<int> number_vector。我需要迭代这个number_vector,例如4次,并在每次迭代中删除第一个最小的数字,即在第一次迭代中我将删除索引1处的值0,在下一次迭代中我将删除索引1 中的0 等。我现在正在执行以下操作:

int n = 7;

int d = 4;

vector<int> number_vector{1, 0, 0, 0, 0, 0 ,0};

for (int counter = 0; counter < n - d; counter++)
{
    int index = distance(number_vector.begin(), min_element(number_vector.begin(), number_vector.end()));

    if (index != number_vector.size() - 1)
    {
        number_vector[index] = move(number_vector.back());
    }

    number_vector.pop_back();

    // number_vector.erase(number_vector.begin() + index);
}

问题在于,如果我运行上面的代码,最后number_vector{1, 0, 0, 0} 而它应该有{1, 0, 0},对于其他情况,如n = 4d = 2number_vector{3, 7, 5, 9},最终的number_vector 具有正确的值,即79。一些提示?

【问题讨论】:

  • std::vector 如果您想在除末尾之外的任何位置插入/删除元素,则数据结构的选择是错误的。我推荐使用std::list。如果您想要O(1) 空间,则每次删除都会花费您O(n) 时间。
  • 使用调试器单步调试代码(如果您不知道如何使用,只需在线搜索)并检查代码的作用。这是找出如此小而孤立的代码中哪里出了问题的最简单方法。
  • 通知您更改剩余元素的顺序。那么std::partial_sort 是可能的。
  • @lucieon - 不一定。在现代 CPU 的小型数据集上,这可能非常快。甚至比列表更快。但他没有说明这些向量有多大。这可能是一个更好的算法。

标签: c++ algorithm vector


【解决方案1】:

首先,您要迭代 3 次,而不是 4 次。其次,如果不需要向量,您可以只使用映射并弹出前面的迭代器,因为它始终是最小值。最后,不需要交换或距离,只要 min_element 的结果不无效就删除它。

【讨论】:

  • 第一:如果我使用counter &lt; d,则第二种情况的值会出错第二:需要矢量,一旦我收到一个数字而不是直接{1, 0...} 最后:我正在删除索引而不是值,当我通过值删除时,会在一次操作中删除多个值,或者对于某些 rason 1 在 0 之前删除
【解决方案2】:

当您从 0 迭代到 n-d 时,n=7 和 d=4。您将从 counter=0 迭代到 counter

我认为你想要的是从 0 迭代到 d。此外,您使用 index.js 会不必要地使代码复杂化。您可以像下面一样直接使用迭代器。

for (int counter = 0; counter < d; counter++)
{   
    *min_element(number_vector.begin(), number_vector.end()) = *number_vector.rbegin();
    number_vector.pop_back();
}   

【讨论】:

  • number_vector.back()*number_vector.rbegin() 更清晰
  • 为什么不简单地number_vector.erase(min_element(...))
  • @RemyLebeau:我想说的是复杂性。
  • @RemyLebeau 因为在删除最后一个元素之前,我们希望将其值保存在 min 元素的位置
【解决方案3】:

你的d是代表向量中pop最小数的次数吗?
然后将counter &lt; n - d修改为counter &lt; d,就会有{1, 0, 0}

11.04 如果你想保持顺序,你可以修改

for (int counter = 0; counter < d; ++counter)
{
    auto iter = min_element(number_vector.begin(), number_vector.end());
    number_vector.erase(iter);
}

PS:std::list 或许是更好的选择?

【讨论】:

  • 是的,d代表了pop的时间,但是就像我说的:'如果我换成d,其他情况都不会通过'
猜你喜欢
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
相关资源
最近更新 更多