C++ 如何遍历字符串并知道索引(当前位置)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1315041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:32:11  来源:igfitidea点击:

How can I iterate through a string and also know the index (current position)?

c++stringiterator

提问by pierrotlefou

Often when iterating through a string (or any enumerable object), we are not only interested in the current value, but also the position (index). To accomplish this by using string::iteratorwe have to maintain a separate index:

通常在遍历字符串(或任何可枚举对象)时,我们不仅对当前值感兴趣,还对位置(索引)感兴趣。为了通过使用实现这一点,string::iterator我们必须维护一个单独的索引:

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

The style shown above does not seem superior to the 'c-style':

上面显示的样式似乎并不优于“c-style”:

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

In Ruby, we can get both content and index in a elegant way:

在 Ruby 中,我们可以优雅地获取内容和索引:

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

So, what is the best practice in C++ to iterate through an enumerable object and also keep track of the current index?

那么,在 C++ 中迭代可枚举对象并跟踪当前索引的最佳实践是什么?

采纳答案by TheUndeadFish

I've never heard of a best practice for this specific question. However, one best practice in general is to use the simplest solution that solves the problem. In this case the array-style access (or c-style if you want to call it that) is the simplest way to iterate while having the index value available. So I would certainly recommend that way.

我从来没有听说过这个特定问题的最佳实践。但是,通常的一种最佳做法是使用解决问题的最简单的解决方案。在这种情况下,数组样式访问(或 c 样式,如果您想调用它)是在索引值可用的情况下进行迭代的最简单方法。所以我肯定会推荐这种方式。

回答by Leandro T. C. Melo

Like this:

像这样:


    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;

回答by Andrew

You can use standard STL function distance as mentioned before

您可以使用前面提到的标准 STL 函数距离

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

Also, you can access string and some other containers with the c-like interface:

此外,您可以使用类似 c 的接口访问字符串和其他一些容器:

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

回答by Alex Reynolds

A good practice would be based on readability, e.g.:

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

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

Or:

或者:

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

Or your original:

或者你的原件:

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

Etc. Whatever is easiest and cleanest to you.

等等。任何对你来说最简单和最干净的东西。

It's not clear there is any one best practice as you'll need a counter variable somewhere. The question seems to be whether where you define it and how it is incremented works well for you.

目前尚不清楚是否有任何最佳实践,因为您需要在某处使用计数器变量。问题似乎是你在哪里定义它以及它是如何增加的。

回答by maxim1000

I would use it-str.begin() In this particular case std::distance and operator- are the same. But if container will change to something without random access, std::distance will increment first argument until it reach second, giving thus linear time and operator- will not compile. Personally I prefer the second behaviour - it's better to be notified when you algorithm from O(n) became O(n^2)...

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

回答by user2015735

Since std::distanceis only constant time for random-access iterators, I would probably prefer explicit iterator arithmetic. Also, since we're writing C++ code here, I do believe a more C++ idiomatic solution is preferable over a C-style approach.

由于std::distance对于随机访问迭代器来说只是常数时间,我可能更喜欢显式迭代器算法。此外,由于我们在这里编写 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;
}

回答by jscharf

For strings, you can use string.c_str()which will return you a const char*, which can be treated as an array, example:

对于字符串,您可以使用string.c_str()which 将返回一个 const char*,它可以被视为一个数组,例如:

const char* strdata = str.c_str();

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