2009-08-22 7 views
43

しばしば列(または任意の列挙オブジェクト)を反復するとき、我々だけでなく、現在の値に興味があるだけでなく、位置(インデックス)。スタイル上は、どのように私は、文字列を反復処理しても、インデックス(現在位置)を知ることができますか?

string str ("Test string"); 
    string::iterator it; 
    int index = 0; 
    for (it = str.begin() ; it < str.end(); it++ ,index++) 
    { 
     cout << index << *it; 
    } 

は、我々は両方のコンテンツを取得することができ、「C-スタイル」Rubyで

string str ("Test string"); 
    for (int i = 0 ; i < str.length(); i++) 
    { 
     cout << i << str[i] ; 
    } 

に優れていないようだようだ:string::iteratorを使用することによって、これを達成するために、我々は別のインデックスを維持する必要がかつエレガントな方法でインデックス:

だから、
"hello".split("").each_with_index {|c, i| puts "#{i} , #{c}" } 

、列挙オブジェクトを反復処理しても、現在のインデックスを追跡するためにC++でのベストプラクティスは何ですか?このよう

答えて

34

この特定の質問のベストプラクティスのしかし、一般的には1つのベストプラクティスは、問題を解決し、最も簡単な解決策を使用することです。この場合、配列スタイルのアクセス(またはそれを呼び出す場合はCスタイル)は、インデックス値を使用できる間に反復する最も簡単な方法です。だから私は確かにその方法をお勧めします。

+0

例がいいです:P –

42

const char* strdata = str.c_str(); 

for (int i = 0; i < str.length(); ++i) 
    cout << i << strdata[i]; 
1

は、あなたがあなたの配列、例として扱うことができるのconstのchar *を、返されたstring.c_str()を使用することができます例えば、読みやすさに基づいて次のようになります。

string str ("Test string"); 
for (int index = 0, auto it = str.begin(); it < str.end(); ++it) 
    cout << index++ << *it; 

または:

string str ("Test string"); 
for (int index = 0, auto it = str.begin(); it < str.end(); ++it, ++index) 
    cout << index << *it; 

またはあなたの元:

string str ("Test string"); 
int index = 0; 
for (auto it = str.begin() ; it < str.end(); ++it, ++index) 
    cout << index << *it; 

等あなたに最も簡単かつクリーンであるものは何でも。

それはあなたがどこかにカウンタ変数が必要になりますよういずれかのベストプラクティスがあるはっきりしていません。質問は、あなたがそれを定義し、それがどのようにインクリメントされた場合、あなたのためにうまく機能するかどうかのようです。

+0

この質問は自分のものと似ていますので、ここで質問したいと思いますが、stardata [i]の値をどのように比較しますか?それをcharに変換する方法はありますか? – frogeyedpeas

6

良い習慣:弦楽のため


    std::string s("Test string"); 
    std::string::iterator it = s.begin(); 

    //Use the iterator... 
    ++it; 
    //... 

    std::cout << "index is: " << std::distance(s.begin(), it) << std::endl; 
+0

私の以前の編集は正しい、@アレックスレイノルズ。 [C++で 'for'ループの初期化本体に異なる型の2つの変数を宣言することはできません。](https://stackoverflow.com/questions/2687392/is-it-possible-to-declareループの異なる2種類の変数)と[this](https://ideone.com/lngBfo)の2つのタイプがあります。 – Bateman

19

また

index = std::distance(s.begin(), it); 

前に述べたようにあなたは、Cのようなインターフェースで、文字列といくつかの他のコンテナにアクセスすることができ、標準のSTL関数距離を使用することができます。私は聞いたことがない

for (i=0;i<string1.length();i++) string1[i]; 
+2

btw、私のインプリメンテーションでは、イテレータ(5x以上)のほうがはるかに高速です – Andrew

3

私は、この特定の場合はstd ::距離とoperator-同じでは )(IT-str.beginを使用します。しかし、コンテナがランダムアクセスなしで何かに変更された場合、std :: distanceは第1引数を2番目に増加し、線形時間を与え、演算子はコンパイルされません。 個人的には、2番目の動作が好きです.O(n)からのアルゴリズムがO(n^2)になったときに通知するほうが良いです...

1

ランダムアクセスイテレータの場合は一定時間ですので、明示的なイテレータ演算を好む。 また、ここではC++コードを記述しているので、CスタイルのアプローチよりもC++の慣用的なソリューションが望ましいと思います。

string str{"Test string"}; 
auto begin = str.begin(); 

for (auto it = str.begin(), end = str.end(); it != end; ++it) 
{ 
    cout << it - begin << *it; 
} 
関連する問題