Я не думаю, что в стандартной библиотеке это подходящий предопределенный алгоритм. В частности, для этого можно использовать std::adjacent_find
, если бы вы определили относительно сложный и предикат с состоянием для него, но это на самом деле означало бы неправильное использование std::adjacent_find
в качестве замены для std::for_each
, то есть это не имело бы большого отношения к первоначальная цель std::adjacent_find
.
Однако вместо голых указателей вы должны использовать итераторы. Я также предлагаю ввести код проверки в отдельную функцию, возможно, названную check
. Вот что я хотел бы предложить:
#include <vector>
#include <map>
#include <iostream>
bool check(const std::vector<std::map<double,double>> &v)
{
/* Fast-forward to the first non-empty entry. */
auto it = begin(v);
for(; it != end(v) ; ++it)
if (!it->empty())
break;
/* We might be done by now. */
if (it == end(v))
return true;
/* Else, go through the remaining entries,
skipping empty maps. */
auto prev = it->end();
advance(prev,-1);
++it;
for (; it != end(v) ; ++it)
{
if (!it->empty())
{
if (it->begin()->first < prev->first)
return false;
prev = it->end();
advance(prev,-1);
}
}
return true;
}
int main()
{
std::vector<std::map<double,double>> v;
/* Two entries for the vector, invalid order. */
v.push_back({ {1.0,1.0} , {2.0,4.0} });
v.push_back({ {3.0,9.0} , {1.0,16.0} });
if (!check(v))
throw std::runtime_error("Invalid order of the maps in the vector.");
return 0;
}
Примечание: Было бы еще более C++ - как (или, по крайней мере, еще как алгоритмы стандартной библиотеки), если вы должны были определить функцию check
как алгоритм, который принимает в качестве аргумента ряд итераторов, а не ссылку на контейнер. Переписывание функции в соответствии с этой концепцией прямолинейно.
Примечание 2: Преимущество использования итераторов вместо обнаженных указателей является то, что вы получаете лучше и чище абстракции, что вам нужно: Что-то, что ссылается на пункт на карте, в то время как double*
указатель может указывать ко всем видам вещей. Тем не менее, существует и недостаток использования итераторов: если вы должны изменить свой алгоритм таким образом, чтобы он изменял карты при повторении через вектор, итератор может быть недействительным, в то время как указатель не будет (если вы не удалите элемент, на который указывает) , (Указатели могут быть признаны недействительными, если вы измените вектор.)
Но пока процедура проверки используется только для проверки и ничего другого (что указывает мой код, помещая код в отдельную функцию, предназначенную для этого назначение, и, взяв вектор в качестве ссылки на const), аннулирование итератора не является проблемой.
Как насчет ссылок вместо этого? Или я недоразумения проблемы? –
@ Н2СО3 Я думал о ссылках, но вы можете присвоить новое значение рефов? –
То, что вы должны использовать, это сами итераторы. Они действуют как указатели. – jogojapan