There is a vector of lines. I cycle through each line, and in each line I cycle through each character again and look for '0'. It is necessary to display the position of this symbol. And the question came up, is it possible to do this without using an additional counter? That is, do only iterators. Thank you in advance.

for(auto line = lines.begin(); line != lines.end(); ++line) { for(auto symbol = (*line).begin(); symbol != (*line).end(); ++symbol) { if (*symbol == '0') { cout << "НомСр символа: " << /*Π½ΠΎΠΌΠ΅Ρ€ символа*/ << endl; } } } 
  • symbol- line->begin() tried? - pavel

2 answers 2

In your particular case, there is nothing to fuss and the garden: calculating the symbol number in a string (meaning std::string ) you can do it simply as symbol - line->begin() .

However, in general, a more abstract case, if you implement an algorithm that, by its nature, does not require random access to the data structure being used, but costs only sequential access, then a more reasonable solution would probably be If you use the counter. Thus, you still maintain the consistent structure of your algorithm, i.e. Solve the problem within a less demanding contract of sequential access.

Using iterator subtraction, you artificially introduce into the purely sequential algorithm a significantly stronger requirement for supporting random access . Do not unnecessarily impose too stringent requirements on data structures. If the task can be solved effectively within the framework of the idea of ​​sequential access, then it is better to solve it within the framework of the idea of ​​sequential access.

For example, if in a purely sequential algorithm you need to replace the vector with a list tomorrow, you will not have to make any alterations in the implementation of your algorithm. But it is enough to add iterator subtraction to such an algorithm - and everything becomes much more complicated.

Be careful with functions like std::distance . This function is intended primarily for the forced concealment of inefficiencies, i.e. in order to silently calculate the distance between iterators even when the iterators do not support effective distance calculation. That is, std::distance is almost always a crutch for very highly specialized situations from the category "here it is impossible to do without distance, even if its calculation is inefficient." Such situations should be carefully avoided.

    To do this, there is a standard function std::distance , declared in the header <iterator> .

    For example,

     cout << "НомСр символа: " << std::distance( (*line).begin(), symbol ) << endl; 

    For random access iterators, as in your case, you can simply subtract one iterator from another

     cout << "НомСр символа: " << symbol - (*line).begin() << endl; 

    But for your case it would be easier to use a normal loop with an index. For example,

     for ( size_t i = 0; i != line->size(); ++i ) { if ( ( *line )[i] == '0') { cout << "НомСр символа: " << i << endl; } } 

    and use this index as a position value.