在 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 ,0
的vector<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_vector
有1, 0, 0, 0
而它应该有1, 0, 0
,对于其他情况,如n = 4
、d = 2
和number_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 < 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 < n - d
修改为counter < 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++ 中删除向量中的第一个最小数字(并保持顺序)的主要内容,如果未能解决你的问题,请参考以下文章