Вектор векторов строк

352
19 октября 2017, 10:58

Имеется класс со структурой и полями:

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 - анализирует учетные записи и выявляет такие, которые используют одинаковый пароль. Результат возвращается в виде вектора векторов строк. Вектор верхнего уровня содержит группы сервисов, между собой использующих одинаковые пароли. Вектор нижнего уровня - это набор названий сервисов, пароль к которым не отличается.

Больше всего интересует вектор векторов, а именно его реализация, и особо не хочется прибегать к конструкции цикла в цикле для сравнивания содержимого вектора. Есть ли какие-то встроенные методы для поиска одинаковых элементов в векторе?

Answer 1

Вариант реализации далеко не один. Могу предложить наспех сделанный:

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;
    }
READ ALSO
Игнорирование условия в While С++

Игнорирование условия в While С++

Задание такое: заполнить матрицу Nного порядка и посчитать

286
Разница между функциями wsprintfW() и swprintf_s()

Разница между функциями wsprintfW() и swprintf_s()

Собственно не могу понять в чем же разница между 2мя этими функциями, когда они дают идентичные результаты

333
Вызов функции из подгружаемого HTML

Вызов функции из подгружаемого HTML

Доброго времени сутокСобственно возникла одна проблема

307