将向量映射到特定范围

时间:2018-12-23 19:59:20

标签: c++ vector stl

我有一个标准向量,例如,包含以下元素

@ngrx/router-store

我需要将这些元素映射到1到4的范围内。即,我需要向量像这样

[-6, -7, 1, 2]

请注意:将第一个向量(-7)中的最小值映射到第二个向量(1)中的最小值。如何使用STL来实现?

3 个答案:

答案 0 :(得分:5)

使用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));

Demo

答案 1 :(得分:5)

仅使用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];
});

生成索引的另一种方法是使用generate_n

vector<int> idxs;
generate_n(back_inserter(idxs),
    values.size(),
    [cnt=1]() mutable { return cnt++; });
// same sort()

答案 2 :(得分:3)

使用成对的辅助向量:

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);
}

Demo


使用成对的helper 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());

Demo