在 C++ 中删除向量中的第一个最小数字(并保持顺序)

Posted

技术标签:

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

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

int n = 7;

int d = 4;

vector<int> number_vector1, 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_vector1, 0, 0, 0 而它应该有1, 0, 0,对于其他情况,如n = 4d = 2number_vector3, 7, 5, 9,最终的number_vector 具有正确的值,即79。一些提示?

【问题讨论】:

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

以上是关于在 C++ 中删除向量中的第一个最小数字(并保持顺序)的主要内容,如果未能解决你的问题,请参考以下文章

查找向量中的第一个缺失元素

我自己的堆栈类中的 C++ 奇怪行为

C++ - 弹出向量的第一个元素

R在向量重复函数中保持随机函数

c++ 向量的 size() 和 capacity()

了解向量乘法