Имеется класс со структурой и полями:
class ProfilesManager
{
public:
struct ProfileData
{
std::string m_serviceName;
std::string m_login;
std::string m_password;
ProfileData(std::string const & _serviceName,
std::string const & _login,
std::string const & _password);
bool operator == (const ProfileData & _profile) const;
bool operator != (const ProfileData & _profile) const;
};
private:
std::string m_userName;
std::vector <ProfileData> m_profiles;
};
Требуется реаливать такой метод:
Метод findServicesWithIdenticalPassword
- анализирует учетные записи и выявляет такие, которые используют одинаковый пароль. Результат возвращается в виде вектора векторов строк. Вектор верхнего уровня содержит группы сервисов, между собой использующих одинаковые пароли. Вектор нижнего уровня - это набор названий сервисов, пароль к которым не отличается.
Больше всего интересует вектор векторов, а именно его реализация, и особо не хочется прибегать к конструкции цикла в цикле для сравнивания содержимого вектора. Есть ли какие-то встроенные методы для поиска одинаковых элементов в векторе?
Вариант реализации далеко не один. Могу предложить наспех сделанный:
public:
std::vector<std::vector<std::string>> findServicesWithIdenticalPassword() const
{
std::vector<std::vector<std::string>> result;
std::vector<ProfileData const*> profiles_view = getProfilesView();
auto sort_view_by_pass = [](ProfileData const *f, ProfileData const *s) {
return f->m_password < s->m_password;/*do check password equivalence*/
};
//Вектор указателей на профили
//Из-за того, что сортируем указатели,
//сами профили в m_profiles местами не меняются
std::sort(profiles_view.begin(), profiles_view.end(), sort_view_by_pass);
for (auto begin = profiles_view.begin(), end = profiles_view.end(); begin != end; /*do nothing*/) {
auto right_border = std::upper_bound(begin, end, *begin, sort_view_by_pass);//Ищем конец последовательности эквивалентных паролей
if (std::distance(begin, right_border) > 1) {
std::vector<std::string> chunk;
chunk.reserve(std::distance(begin, right_border));
//Копируем имена сервисов в chunk
std::transform(
begin,
right_border,
std::back_inserter(chunk),
[](ProfileData const *profile) -> const std::string & {
return profile->m_serviceName; /*do getServiceName call*/
}
);
result.emplace_back(std::move(chunk));
}
begin = right_border;
}
return result;
}
private:
std::vector<ProfileData const*> getProfilesView() const
{
std::vector<ProfileData const*> profiles_view(m_profiles.size());
std::iota(profiles_view.begin(), profiles_view.end(), m_profiles.data());
return profiles_view;
}
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Собственно не могу понять в чем же разница между 2мя этими функциями, когда они дают идентичные результаты