присваивание vs std :: swap и объединение и хранение дубликатов в отдельном объекте - PullRequest
1 голос
/ 06 марта 2011

Скажите, у меня есть два std::set<std::string> с.Первый, old_options, необходимо объединить с дополнительными параметрами, содержащимися в new_options.Я не могу просто использовать std::merge (хорошо, но не только это), потому что я также проверяю удваивания и соответственно предупреждаю пользователя об этом.Для этого у меня есть

void merge_options( set<string> &old_options, const set<string> &new_options )
{
    // find duplicates and create merged_options, a stringset containing the merged options
    // handle duplicated the way I want to
    // ...
    old_options = merged_options;
}
  1. . Лучше ли использовать

    std::swap( merged_options, old_options );
    

    или мое назначение?

  2. Есть ли лучший способ отфильтровать дубликаты и вернуть объединенные set, чем последовательные вызовы, на std::set_intersection и std::set_union, чтобы обнаружить дубликаты и объединить set с?Я знаю, что он медленнее, чем один обход, и делает оба одновременно, но эти наборы малы (производительность не критична), и я доверяю Стандарту больше, чем себе.

Ответы [ 3 ]

1 голос
/ 06 марта 2011

Что не так с

void merge_options( set<string> &old_options, const set<string> &new_options )
{
    for (set<string>::iterator i = new_options.begin();
         i != new_options.end(); ++i)
        if (old_options.find(*i) != old_options.end())
            warn_duplicate(*i);
        else
            old_options.insert(*i);
}

Это простой алгоритм O ( m lg n ), где m = new_options.size() и n = old_options.size().

1 голос
/ 07 марта 2011

Это частично ответ ларманов. Существует алгоритм remove_copy_if, который заключает его цикл for в одну функцию. Следующее использует лямбду C ++ 0x для предиката.

void merge_options( set<string> &old_options, const set<string> &new_options )
{
    remove_copy_if(
        new_options.begin(),
        new_options.end(),
        inserter(old_options, old_options.end()),
        [&](const string &s) {
            return (old_options.count(s)) ? warn_duplicate(s), true : false;
        }
    );
}
1 голос
/ 06 марта 2011

Учитывая (как вы заявили), что производительность здесь не критична, я бы использовал назначение и двухпроходный алгоритм.Это проще и легче понять;Стоит использовать «трюк», такой как своп, если вам действительно нужно то, что он получает.

Написание собственного алгоритма не будет такой уж плохой вещью, но, опять же, если вы не используете его на практике.обеспечивает, я бы не стал беспокоиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...