在C++中调整向量中的索引

Adjusting index in a vector in C++

本文关键字:索引 向量 调整 C++      更新时间:2023-10-16

我正在编写一个代码,其中矢量索引的值按照它们所包含元素的排序顺序显示:

例如:

values  -> 3 2 4 1 5
indices -> 1 2 3 4 5    //yeah I know C++ indexing starts with 0. Well, while printing, I will add 1
result  -> 4 2 1 3 5    //Bear with me. I know its confusing. I will clarify below

现在,通过对元素进行排序并打印它们的早期索引,已经获得了结果。

类似:

values(sorted)           -> 1 2 3 4 5
indices(before sorting)  -> 4 2 1 3 5

现在,有很多方法可以做到这一点,有些方法建议存储以前的值并搜索和打印以前的索引,而另一些方法则建议创建一个新的向量并复制其中的以前索引,然后对它们进行排序。。。。(好吧,我没有进一步阅读,因为这绝对不是我要做的(

我尝试了一种不同的方法,同时尽量不使用第二个向量。因此,方法如下:

while (!vec_students.empty()) {
std::vector<int>::iterator iterator = std::min_element(vec_students.begin(), vec_students.end());
std::cout << std::distance(vec_students.begin(), iterator) + 1 << " ";
vec_students.erase(iterator);
}

现在,在这种方法中,我面临的问题是,一旦我使用擦除,所有元素的索引都会减少一定的增量值。这就是我想到的解决方案:

while (!vec_students.empty()) {
static int i = 0;    //yeah I know standard static variables are initialised to 1.
std::vector<int>::iterator iterator = std::min_element(vec_students.begin(), vec_students.end());
std::cout << std::distance(vec_students.begin(), iterator) + i << " ";
vec_students.erase(iterator);
i++;
}

现在的想法是这样的:初始解决方案:

vector:  2 3 1
expected output: 3 1 2 (For explanation refer above)
first index = indexof(min(2,3,1)) -> 2 (while printing add 1) -> 3
second index = indexof(min(2,3)) -> 0 (while printing....) -> 1
third index = indexof(min(3)) -> 0 (while...) -> 1

然后我意识到向量大小减小了,这意味着索引将减少(在这种情况下减少1(

所以我添加了额外的i。解决方案工作:

vector: 2 3 1         i = 0
first index = indexof(min(2,3,1)) -> 3 -> add i -> 3 -> increment i -> i = 1
second index = indexof(min(2,3)) -> 0 -> add i -> 1 -> increment i -> i = 2
third index = indexof(min(3)) -> 0 -> add i -> 2 -> increment i -> i = 3

并且程序结束。

但在上面的情况下,我得到的不是3 1 2,而是3 2 3(第一个值正确,其余值增加1(

我的逻辑出了什么问题?

所有元素的索引都会减少一定的增量值。

不是所有的,只是在您删除的那个之后的那些。这里有一种不用制作另一个矢量的方法:

#include <algorithm>
#include <iostream>
#include <limits>
#include <vector>
int main() {
std::vector<int> v{3, 2, 4, 1, 5};
auto const* beg = v.data();
auto sz = v.size();
while (sz--) {
auto const min = std::min_element(v.begin(), v.end());
std::cout << &*min - beg << ' ';
*min = std::numeric_limits<int>::max();
}
}

如果向量中有INT_MAX,这将无法正常工作。无论如何,制作第二个矢量可以得到更好的解决方案。一个例子:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<int> v{3, 2, 4, 1, 5};
std::vector<int const*> addresses;
addresses.reserve(v.size());
std::transform(v.cbegin(), v.cend(), std::back_inserter(addresses),
[](auto const& elm) { return &elm; });
std::sort(addresses.begin(), addresses.end(),
[](int const* const ptr1, int const* const ptr2) {
return *ptr1 < *ptr2;
});
for (auto* p : addresses) {
std::cout << p - v.data() << ' ';
}
}

您认为应该添加索引,因为矢量是收缩的。

好吧,不是真的,只有之后的才应该影响删除的元素。


示例。

[2,1,3] => [2,3]

2的指数保持在0,

而CCD_ 7的索引从CCD_ 9 变为CCD_