3
\$\begingroup\$

This code kinda hurts my feelings -- everything else in my code is done in neat one-liners, exploiting algorithms and, sometimes boost::bind, except for this piece. To say nothing about awkward if(b!=a).

Is there a better way to do the task?

#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;
}
\$\endgroup\$
2
\$\begingroup\$

(Let's start over.)

It generally looks good. You have to have two loops because you want pairs, one way or another. But if you want all off-diagonal pairs, i.e. if you mean "unequal index" rather than "unequal value", you don't need the conditional:

    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";
    }

If you mean pairs of unequal values, you could start like this:

    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";
    }

However, this still produces redundant output, since you don't track repeated values in the outer loop (which should be "for all unique a in the list). In that case it might be nicer to use a set of pairs container perhaps, with a suitable predicate.

\$\endgroup\$
2
\$\begingroup\$

Also not really pretty, but perhaps a start

#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;
}

It's C++0x because I was too lazy to write a functor for that lambda and I don't know the Boost.Lambda syntax off the top of my head.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.