Перебора неравные неупорядоченных пар в одной коллекции


Этот код немного ранит мои чувства ... все остальное в моем коде это делается в аккуратные острот, используя алгоритмы и, иногда повышение::связать, кроме этого куска. Не говоря уже о неловко , если(B!=а).

Есть ли лучший способ, чтобы сделать задачу?

#include <iostream>
#include <list>
using namespace std;

int main()
{
    int arr[] = {1,2,3,4,5,6};
    list<int> lst(arr,arr+sizeof(arr)/sizeof(int));

    for(list<int>::iterator a = lst.begin(); a != lst.end();a++)
    {
            for(list<int>::iterator b = a; b != lst.end(); b++)
                    if(b != a) cout << " ("<<*a<<","<<*b<<")";
            cout << "\n";
    }
    return 0;
}


495
3
задан 1 июля 2011 в 12:07 Источник Поделиться
Комментарии
2 ответа

(Давай начнем сначала.)

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

    for (list<int>::const_iterator a = lst.begin(), b, end = lst.end(); a != end; )
{
for (b = ++a; b != end; ++b) cout << " (" << *a << ", " << *b << ")";
cout << "\n";
}

Если вы имеете в виду пары неравных значений, вы могли бы начать так:

    for (list<int>::const_iterator a = lst.begin(), b, end = lst.end(); a != end; )
{
for (b = ++a; b != end; ++b) if (*b != *a) cout << " (" << *a << ", " << *b << ")";
cout << "\n";
}

Однако, это все еще производит избыточные мощности, так как вы не отслеживать повторяющиеся значения во внешнем цикле (который должен быть "для всех уникальные , а в списке). В этом случае было бы лучше использовать набор из контейнера пар, возможно, с помощью подходящего предиката.

2
ответ дан 2 июля 2011 в 11:07 Источник Поделиться

Также не очень красиво, но, возможно, начать

#include <algorithm>
#include <iostream>
#include <list>
using namespace std;

int main()
{
list<int> lst = {1,2,3,4,5,6};

auto a = lst.cbegin();
int first = *a;
auto output_pairs = [&first](const int second){ cout << " ("<<first<<','<<second<<')'; };
while(++a != lst.cend())
{
for_each(a, lst.cend(), output_pairs);
cout << '\n';
first = *a;
}
cout << flush;
}

Это c++0х, потому что я был слишком ленив, чтобы написать функтор для лямбды и я не знаю наддува.Синтаксис лямбда с верхней части моей головы.

2
ответ дан 1 июля 2011 в 11:07 Источник Поделиться