我怎样才能遍历一个string,也知道索引(当前位置)?

通常在迭代string(或任何可枚举对象)时,我们不仅对当前值感兴趣,而且对位置(索引)也感兴趣。 要通过使用string::iterator来实现这一点,我们必须保持一个单独的索引:

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

以上的风格似乎并不比“C风格”

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

在Ruby中,我们可以通过优雅的方式获得内容和索引:

  "hello".split("").each_with_index {|c, i| puts "#{i} , #{c}" } 

那么,C ++中的最佳做法是遍历一个可枚举对象并跟踪当前索引?

我从来没有听说过这个具体问题的最佳做法。 但是,一般来说,最好的做法是使用解决问题的最简单的解决scheme。 在这种情况下,数组样式的访问(或c样式,如果你想调用它)是最简单的方法来迭代,同时有索引值可用。 所以我肯定会推荐这种方式。

喜欢这个:

 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; 

如前所述,您可以使用标准的STLfunction距离

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

此外,你可以访问string和其他一些类似c接口的容器:

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

一个好的做法是基于可读性,例如:

 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; 

等等无论对你来说最简单,最干净。

目前还不清楚有什么最佳做法,因为你需要一个计数器variables。 这个问题似乎是你在哪里定义它,以及它是如何递增的。

我会使用它str.begin()在这种特殊情况下,std :: distance和operator-是相同的。 但是,如果容器将变成没有随机访问的东西,std :: distance将增加第一个参数,直到达到第二个,给线性时间和操作符 – 将不会编译。 我个人更喜欢第二种行为 – 当O(n)的algorithm变成O(n ^ 2)时,最好得到通知。

对于string,你可以使用string.c_str() ,它将返回一个const char *,它可以被当作一个数组,例如:

 const char* strdata = str.c_str(); for (int i = 0; i < str.length(); ++i) cout << i << strdata[i]; 

由于std::distance对于随机访问迭代器只是恒定的时间,所以我可能更喜欢显式迭代器algorithm。 另外,因为我们在这里编写C ++代码,所以我相信更多的C ++惯用的解决scheme比C风格的方法更可取。

 string str{"Test string"}; auto begin = str.begin(); for (auto it = str.begin(), end = str.end(); it != end; ++it) { cout << it - begin << *it; }