我有一个标准向量包含,例如,以下元素
[-6, -7, 1, 2]
我需要将这些元素映射到1到4的范围.即我需要向量这样
[2, 1, 3, 4]
注意:第一个向量(-7)中的最小值被映射到第二个向量(1)中的最小值.如何用STL实现这一目标?
使用range-v3:
std::vector<int> v{-6, -7, 1, 2};
auto res = ranges::view::ints(1, 1 + (int)v.size()) | ranges::to_vector;
ranges::sort(ranges::view::zip(v, res));
Run Code Online (Sandbox Code Playgroud)
只有C++ 17中存在的标准库(或者实际上是C++ 11),您可以创建索引向量并对其进行排序 - 使用自身作为投影:
vector<int> idxs(values.size());
iota(idxs.begin(), idxs.end(), 1);
sort(idxs.begin(), idxs.end(), [&](int i, int j){
return values[i-1] < values[j-1];
});
Run Code Online (Sandbox Code Playgroud)
生成索引的另一种方法是使用generate_n:
vector<int> idxs;
generate_n(back_inserter(idxs),
values.size(),
[cnt=1]() mutable { return cnt++; });
// same sort()
Run Code Online (Sandbox Code Playgroud)
使用成对的辅助向量:
std::vector<int> a { -6, -7, 1, 2 };
std::vector<std::pair<int, int>> tmp;
for (int i = 0; i < (int) a.size(); ++i) {
tmp.push_back({ a[i], i });
}
std::sort(tmp.begin(), tmp.end());
std::vector<int> b;
for (auto & x : tmp) {
b.push_back(x.second + 1);
}
Run Code Online (Sandbox Code Playgroud)
使用成对的辅助priority_queue(以避免显式排序):
std::vector<int> a { -6, -7, 1, 2 };
std::priority_queue<std::pair<int, int>> tmp;
for (std::size_t i = 0; i < a.size(); ++i) {
tmp.push({ -a[i], i});
}
std::vector<int> b;
do {
b.push_back(tmp.top().second + 1);
} while (tmp.pop(), !tmp.empty());
Run Code Online (Sandbox Code Playgroud)