algo/search: add balanced scan

This commit is contained in:
Danny Robson 2020-02-27 07:59:22 +11:00
parent f34d5ce278
commit dc46d2d52b

View File

@ -63,4 +63,38 @@ namespace cruft::search {
return std::pair (std::move (best_score), std::move (best_item)); return std::pair (std::move (best_score), std::move (best_item));
} }
/// Performs a linear scan of the range specified by `begin` through `end`
/// and returns the first iterator where the number of occurrences of
/// values that match `open` equal the number of values that match `close`.
///
/// eg, it can be used to find matching parenthesis in an expression like:
/// "((1+1)/(2))"
///
/// The user _probably_ wants `begin` to return a value that equals `open`
/// in the first instance (otherwise the algorithm will return `begin`
/// immediately. But it is not an error to do so.
template <typename IteratorT>
IteratorT
balanced (
IteratorT begin,
IteratorT const end,
std::add_const_t<typename std::iterator_traits<IteratorT>::reference> open,
std::add_const_t<typename std::iterator_traits<IteratorT>::reference> close
) {
int count = 0;
for ( ; begin != end; ++begin) {
auto const &val = *begin;
if (val == open)
++count;
else if (val == close)
--count;
else if (count == 0)
return begin;
}
return end;
}
} }