In the following code, is there an elegant way to find it_end
?
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <type_traits>
template <class Iterator, class U = typename std::iterator_traits<Iterator>::value_type>
void process(Iterator begin, Iterator end)
{
// first nonzero
auto it_begin = std::find_if(begin, end, [](U val){return val != 0;});
// end of nonzero values
int n = std::distance(begin, end);
int index = n-1;
for(int i=n-1; i>=0; --i) {
if(*(begin+i) == 0) {
index = i;
} else {
break;
}
}
auto it_end = begin;
std::advance(it_end, index);
// ******* is there a way to use std::find_if or similar function to get it_end? *******
for(auto it=it_begin; it!=it_end; ++it) {
// a whole bunch of things
// ...
std::cout << *it << std::endl;
}
}
int main()
{
std::vector<int> v{0,0,1,2,3,0,0};
process(v.begin(), v.end());
}
use std::reverse_iterator.
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <type_traits>
#include <list>
template <class Iterator, class U = typename std::iterator_traits<Iterator>::value_type>
void process(Iterator begin, Iterator end)
{
// first nonzero
auto it_begin = std::find_if(begin, end, [](U val){return val != 0;});
if (it_begin == end)
return; // all value is zeros.
// reverser iterator
auto r_begin = std::reverse_iterator(end);
auto r_end = std::reverse_iterator(it_begin);
auto r_find = std::find_if(r_begin, r_end, [](U val) { return val != 0; });
auto it_end = r_find.base();
for(auto it = it_begin; it != it_end; ++it) {
std::cout << *it << std::endl;
}
}
int main()
{
std::list<int> v{0,0,0,2,0,3,4};
process(v.begin(), v.end());
}
You can use the reverse iterator .
My implementation:
template <class Iterator, class U = typename std::iterator_traits<Iterator>::value_type>
void yet_another_process(Iterator begin, Iterator end, std::reverse_iterator<Iterator> rbegin, std::reverse_iterator<Iterator> rend) {
auto it_begin = std::find_if(begin, end, [](U val) { return val != 0; });
auto it_end = std::find_if(rbegin, rend, [](U val) { return val != 0; }).base(); // Notice this base()
for (auto it = it_begin; it != it_end; ++it) {
std::cout << *it << std::endl;
}
}
and in main()
:
int main() {
std::vector<int> v { 0, 0, 1, 2, 3, 0, 0 };
yet_another_process(v.begin(), v.end(), v.rbegin(), v.rend());
}
The base()
method of a reverse iterator returns the underlying "normal" iterator.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.