использует RangeMut(которым он владеет) по значениям BTreeMap(которым он НЕ владеет). Итератор возвращает значения, связанные временем жизни с BTreeMap, которым он не владеет.
В ряде случаев мне нужно, чтобы Итератор продвигал RangeMut к заданному известному ключу.
У RangeMut нет такого функционала. Тривиальное рашение этой задачи — это просто в цикле вызывать next() у итератора RangeMut. Но в этом случае эффективность продвижения будет O(m), где m — число элементов, которые я заскипал. Это решение, на первый взгляд, неэффективно, так как BTreeMap, вообще говоря, это коллекция с бинарным поиском. То есть продвинуться, теоретически, можно было бы за логарифмическое время от m, а не за линейное. И хотелось бы так и сделать.
Чтобы перепрыгнуть за логарифмическое время можно было бы пересоздать RangeMut, но я этого сделать не могу, так как Итератор не владеет исходным BTreeMap.
Как эту задачу можно было бы решить?
Монжо например не пользоваться итераторами, просто делать доступ по индексу, мутабельно одалживая нужные элементы
Интересная мысль, но доступ по индексу будет каждый раз иметь логарифмическое время. Это получится сильно дороже. Кроме того, мы потеряем кеш.
А ты уверен, что итерация не log(n)?
Абсолютно уверен. Это же BTree+
O(log(n)) вызов next в худшем случае, но O(1) в среднем И O(log(n) + k) на вызов next k раз подряд
Тогда всё будет зависеть от того, сколько ты скипаешь и сколько итерируешь. Если например скипаешь большие интервалы, может есть смысл пересоздавать итератор, чтобы по тем, которые НЕ скипаешь идти за O(1). Ну и может на другую структуру тоже есть смысл посмотреть. Сортированный вектор например.
Спасибо за содержательный ответ )
Обсуждают сегодня