Вложение c ++ 11 циклов диапазона для поиска комбинаций

Нахождение комбинации включает в себя две петли над одним контейнером.

the first iterates over elements:
pick an element
iterate over the elements on the left
print the first and the second iterated elements

так вот неправильный пример:

vector<int> vec;
for(size_t i=0; i< 10 ; ++i) vec.push_back(i);
for(auto i : vec)
{
auto j = i.increaseBy(1);
for(j : vec) cout << i << j << "\n";
}

В этом вопросе меня интересует, есть ли в синтаксисе циклов диапазона нечто большее, чем простой способ перебора элементов. не так много документации по c ++ 11.

1

Решение

Предполагая, что вы хотите перебрать [(v[i], v[j]) | i <- [0..v.size()], j <- [0..i]] (используя псевдокод с синтаксисом понимания списка), затем вы можете сделать следующее с небольшой помощью Boost.Range:

for(auto i: boost::irange(0, v.size()))
for(auto j: boost::irange(0, i)) {
// use v[i] and v[j]
}

Помимо примера, ответ на ваш вопрос заключается в том, что нет, предложение диапазона не делает много магии. Это также не расширяемо. Тем не менее, хорошая новость заключается в том, что есть еще один способ взглянуть на это: выражение диапазона для может быть довольно глупым, но диапазоны могут быть настолько умными, насколько они хотят.

Это означает, что хотя range-for может выполнять итерации только по элементам диапазона, этот диапазон не имеет, например, сопоставить с существующим существующим контейнером, вопреки тому, что вы, похоже, ожидаете. Например, это

namespace A = boost::adaptors;
for(auto&& e: A::strided(v, 2)) foo(e);

звонки foo на каждом другом элементе v, Работа здесь сделана strided, а не диапазон для заявления.

Я не могу придумать краткий способ выразить ваш пример в одном диапазоне даже с помощью Boost.Range. Это не значит, что это невозможно, и я исследовал некоторую форму понимания списков в C ++ в прошлом. Однако инструментов для его выражения сегодня здесь нет.

7

Другие решения

Я предполагаю, что вы ищете коллекцию пары векторных элементов.

Это не то, для чего предназначен цикл на основе диапазона. Циклы, основанные на диапазоне, предназначены для итерации по всей коллекции, когда каждый элемент просматривается ровно один раз. Не используйте их ни для чего другого. То, что это новая, добавленная языковая функция, не означает, что вам придется отбрасывать все, что вы когда-либо знали. Новая функция обогащать язык, они не замещать Это.

Вот как можно получить уникальные пары:

for (auto it1 = vec.begin(), end = vec.end(); it1 != end; ++it1)
{
for (auto it2 = std::next(it1); it2 != end; ++it2)
{
std::cout << "[" << *it1 << ", " << *it2 << "]\n";
}
}

Если вы также хотите включить диагональные элементы (it1, it1), просто замените вторую инициализацию на auto it2 = it1,

4

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector