Сначала вы можете создать два репозитория, которые будут содержать полный список пользователей с одной стороны и полный список каналов с другой.Как правило, вы делаете это с maps :
map<int, User> users;
map<std::string, Channel> channels;
Тогда я бы предложил иметь для каждого канала набор пользователей:
class Channel {
private:
std::string name;
std::set<int> subscribers;
public:
Channel(std::string name):name(name) { };
void add(int userid) {
subscribers.insert(userid);
}
};
Затем, чтобы найти пользователей, не связанных с каналом, вы можете перебирать пользователей и легко проверять, включены ли они в канал.
Кроме того, вы также можете использовать глобальный набор пользователей (либо поддерживая членство в наборе в то же время, что и хранилище, либо создавая набор из карты ) и использовать set_difference()
для генерации набора пользователей, которые не являются подписчиками.
Пример использования из set_difference
:
set<int> a { 1,2,3,4,5,6,7}; // imagine a set of all the users
set<int> b{ 2,3,8}; // imagine a set of the subscribers of a channel
vector<int> c; // container with the users who are not subscribers
set_difference(a.begin(),a.end(), b.begin(), b.end(), back_inserter(c));
copy(c.begin(), c.end(), ostream_iterator<int>(cout," "));
Как выбрать между двумя подходами?Первый подход, повторяющийся и проверяющий, имеет то преимущество, что позволяет быстро найти первых пользователей и начать что-то делать с предложением.Итерацию можно оптимизировать, используя тот факт, что наборы и карты отсортированы.Вам не нужно найти всех пользователей.Второй подход элегантен, но с большой базой пользователей, это может занять больше времени, так как вам нужно получить полный результат, прежде чем что-либо делать.