int v1とv2の2つのソートされていないベクトルがあり、v1にはv2のサブセットが含まれています
v1: 8 12 4 17
v2: 6 4 14 17 9 0 5 12 8
v1のアイテムをv2の位置のインデックスに置き換える方法はありますか?
v1: 8 7 1 3
サイクルに2を使用してこのようなアルゴリズムを記述しても問題ありません...
しかし、std :: transformを使用して使用する解決策はありますか?
std::transform
以下を呼び出す関数オブジェクトと組み合わせるstd::find
:
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
struct find_functor
{
std::vector<int> &haystack;
find_functor(std::vector<int> &haystack)
: haystack(haystack)
{}
int operator()(int needle)
{
return std::find(haystack.begin(), haystack.end(), needle) - haystack.begin();
}
};
int main()
{
std::vector<int> v1 = {8, 12, 4, 17};
std::vector<int> v2 = {6, 4, 14, 17, 9, 0, 5, 12, 8};
// in c++11:
std::transform(v1.begin(), v1.end(), v1.begin(), [&v2](int x){
return std::find(v2.begin(), v2.end(), x) - v2.begin();
});
// in c++03:
std::transform(v1.begin(), v1.end(), v1.begin(), find_functor(v2));
std::cout << "v1: ";
std::copy(v1.begin(), v1.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
出力:
$ g++ -std=c++0x test.cpp
$ ./a.out
v1: 8 7 1 3
std::find()
変換で使用できます:
std::transform(v1.begin(), v1.end(), v1.begin(), [&](int v)->int {
return std::find(v2.begin(), v2.end(), v) - v2.begin());
});
std::transform
単項関数のようなオブジェクトを取ります。したがって、この操作を効率的に実行するファンクタークラスを作成し、2番目のベクトルで構築してから、そのファンクターを最初のベクトルに適用できます。
template <typename T>
class IndexSeeker{
private:
map<T, int> indexes;
public:
IndexSeeker(vector<T> source){
for(int k = 0; k < t.size(); ++k){
indexes[source[k]] = k;
}
}
int operator()(const T& locateme){
if(indexes.find(T) != indexes.end()){
return indexes[T];
}
return -1;
}
}
2番目のリスト全体をマップにキャッシュすることにより、線形検索を必要とせずに、インデックスを効率的に見つけることができます。これには、タイプTがソート可能(したがってマッピング可能)である必要があります。Tがソート可能でない場合は、ブルートフォース検索を必要とする効率の低いアプローチが必要です。