目的は、[]演算子や「at」メソッドではなく、文字列のベクトルの「n番目」の要素にアクセスすることです。私が理解していることから、コンテナをナビゲートするためにイテレータを使用できますが、これまでイテレータを使用したことがなく、読んでいるものは混乱しています。
これを達成する方法について誰かが私にいくつかの情報を提供できたら、私はそれを感謝します。ありがとうございました。
目的は、[]演算子や「at」メソッドではなく、文字列のベクトルの「n番目」の要素にアクセスすることです。私が理解していることから、コンテナをナビゲートするためにイテレータを使用できますが、これまでイテレータを使用したことがなく、読んでいるものは混乱しています。
これを達成する方法について誰かが私にいくつかの情報を提供できたら、私はそれを感謝します。ありがとうございました。
回答:
クラスのbegin
およびend
メソッドを使用する必要がありvector
ます。これは、最初と最後の要素をそれぞれ参照する反復子を返します。
using namespace std;
vector<string> myvector; // a vector of stings.
// push some strings in the vector.
myvector.push_back("a");
myvector.push_back("b");
myvector.push_back("c");
myvector.push_back("d");
vector<string>::iterator it; // declare an iterator to a vector of strings
int n = 3; // nth element to be found.
int i = 0; // counter.
// now start at from the beginning
// and keep iterating over the element till you find
// nth element...or reach the end of vector.
for(it = myvector.begin(); it != myvector.end(); it++,i++ ) {
// found nth element..print and break.
if(i == n) {
cout<< *it << endl; // prints d.
break;
}
}
// other easier ways of doing the same.
// using operator[]
cout<<myvector[n]<<endl; // prints d.
// using the at method
cout << myvector.at(n) << endl; // prints d.
std::vector
ランダムアクセス反復子を持つという事実を見逃しています。
std::advance(it, n)
です。それはあなたが望むことを正確に実行するように定義されてit + n
おり、イテレータがランダムアクセスとしてタグ付けされている場合は自動的に使用し、そうでなければループを実行します。
通常、イテレータはコンテナの要素に線形的にアクセスするために使用されます。ただし、「ランダムアクセス反復子」を使用すると、と同じ方法で任意の要素にアクセスできますoperator[]
。
ベクトルでのアクセス任意の要素 vec
は、次のように使用することができます。
vec.begin() // 1st
vec.begin()+1 // 2nd
// ...
vec.begin()+(i-1) // ith
// ...
vec.begin()+(vec.size()-1) // last
以下は、典型的なアクセスパターンの例です(以前のバージョンのC ++)。
int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
イテレータを使用する利点は、他のコンテナでも同じパターンを適用できることです。
sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
sum += *it;
}
このため、コンテナタイプに関係なく同じように機能するテンプレートコードを作成するのは非常に簡単です。イテレータのもう1つの利点は、データがメモリに常駐していることを前提としないことです。たとえば、入力ストリームからデータを読み取ることができる、またはその場でデータを生成するだけのフォワードイテレータ(たとえば、範囲または乱数ジェネレータ)を作成できます。
std::for_each
とラムダを使用する別のオプション:
sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
C ++ 11以降でauto
は、これまでに見た(またはさらに複雑な)非常に長く複雑なイテレータの型名を指定しないようにすることができます。
sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
また、さらに簡単なfor-eachバリアントもあります。
sum = 0;
for (auto value : vec) {
sum += value;
}
最後にstd::accumulate
、整数と浮動小数点のどちらを追加するかに注意する必要がある場合もあります。
C ++-11では、次のことができます。
std::vector<int> v = {0, 1, 2, 3, 4, 5};
for (auto i : v)
{
// access by value, the type of i is int
std::cout << i << ' ';
}
std::cout << '\n';
バリエーションについてはこちらをご覧ください:https : //en.cppreference.com/w/cpp/language/range-for
7.5.0
Ubuntu 18.04 でgcc を試してみて、アレイと同じように機能します。
Vectorのイテレータはランダムアクセスイテレータです。つまり、単純なポインタのように見えます。
コンテナーのbegin()
メソッドから返されたイテレーターにnを追加することにより、n番目の要素にアクセスできます[]
。または、operatorを使用できます。
std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();
int sixth = *(it + 5);
int third = *(2 + it);
int second = it[1];
代わりに、あらゆる種類のイテレータで機能するアドバンス関数を使用できます。(非ランダムアクセスのイテレータを使用して「ランダムアクセス」を本当に実行するかどうかを検討する必要があります。これはコストがかかるためです。)
std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();
std::advance(it, 5);
int sixth = *it;
advance
ランダムアクセス反復子や不明なカテゴリの反復子にも使用できます。その場合、一定の時間で動作することが保証されているためです。これが、ユーザー定義のイテレータに正しくタグを付ける必要がある理由です。
advance
ランダムアクセスイテレータを扱っていることがわかっている場合は、(outパラメータを使用しているため)本当に面倒です。汎用コードでのみ推奨され、あまり使用されない場合(アルゴリズムが非ランダムアクセス反復子を適切にサポートしていない場合はそうなるでしょう-たとえば、ソートすることはstd::sort
できますが、途方もstd::list
なく非効率であるためです) )。
operator+
。しかし、問題は明示的にベクトルに関するものだったので、答えの最初の部分に問題はありません。2番目の部分は、「ランダムアクセスイテレータでAdvanceを使用することはできません」と、これまでに見たことのない人に示唆しているのではないかと思いましたadvance
。
Vector
は小文字にする必要があります
2つの反復子をインクリメントする必要のないループ内でを使用してのith
インデックスにアクセスする例を次に示します。std::vector
std::iterator
std::vector<std::string> strs = {"sigma" "alpha", "beta", "rho", "nova"};
int nth = 2;
std::vector<std::string>::iterator it;
for(it = strs.begin(); it != strs.end(); it++) {
int ith = it - strs.begin();
if(ith == nth) {
printf("Iterator within a for-loop: strs[%d] = %s\n", ith, (*it).c_str());
}
}
forループなし
it = strs.begin() + nth;
printf("Iterator without a for-loop: strs[%d] = %s\n", nth, (*it).c_str());
そしてat
メソッドを使用して:
printf("Using at position: strs[%d] = %s\n", nth, strs.at(nth).c_str());