From dc46d2d52bf0d778d6fd897aca588b4729df3927 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Thu, 27 Feb 2020 07:59:22 +1100 Subject: [PATCH] algo/search: add balanced scan --- algo/search.hpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/algo/search.hpp b/algo/search.hpp index bfcba7d2..1cc4ba8e 100644 --- a/algo/search.hpp +++ b/algo/search.hpp @@ -63,4 +63,38 @@ namespace cruft::search { 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 + IteratorT + balanced ( + IteratorT begin, + IteratorT const end, + std::add_const_t::reference> open, + std::add_const_t::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; + } } \ No newline at end of file