There are some things I am not sure of from a professional standpoint about the correct way to write C++ code. I have been looking through source code produced by various opensource projects, as well as other code posted here and on Stack Overflow. So let's just leave it at this. Let's say I am interviewing for company A over the phone. Not white board yet. They ask me to write the code below and turn it in a hour. This is a hypothetical situation, however it parallels how most big companies are interviewing nowadays. Would this code get me the job? If not, what would you change, or what can you coach me with so I can get a job programming?#include <iostream>#include <queue>#include <algorithm>#include <iterator>/*  * This program reads a sequence of pairs of nonnegative integers * less than N from standard input (interpreting the pair p q to * mean connect object p to object q) and prints out pair  * representing objects that are not yet connected. It maintains an * array id that has an entry for each object, with the property * that id[p] and id[q] are equal if and only if p and q are  * connected. */static const int N = 10;int main( int argc, char *argv[ ] ){    /*     * Ease the type of long types     */     typedef std::ostream_iterator<int> output_data;    typedef typename std::vector<int>::iterator v_it;    /*     * Generate Test Data     */    std::pair<int,int> pairs[12] = {                                     std::pair<int,int>( 3,4 ),                                    std::pair<int,int>( 4,9 ),                                    std::pair<int,int>( 8,0 ),                                    std::pair<int,int>( 2,3 ),                                    std::pair<int,int>( 5,6 ),                                    std::pair<int,int>( 2,9 ),                                    std::pair<int,int>( 5,9 ),                                    std::pair<int,int>( 7,3 ),                                    std::pair<int,int>( 4,8 ),                                    std::pair<int,int>( 5,6 ),                                    std::pair<int,int>( 0,2 ),                                    std::pair<int,int>( 6,1 )                                  };    /*     * Load Test Data onto Queue     */     std::queue<std::pair<int,int> > queue;    for( int x=0;x<12;x++ )    {        queue.push( pairs[x] );    }    /*     * Data strucutre to represent nodes in graph.     * An index in the vector is an id for a node.     */      std::vector<int> id;    /*     * Start the nodes as not being connected     */      id.reserve( N );    for( int i = 0;i<N;i++ ) id.push_back( i );    std::cout << p q\t;    /*     * Output the data     */      copy( id.begin( ), id.end( ), output_data( std::cout,   ) );    std::cout << std::endl;    std::cout << ------------------------------------;    std::cout << std::endl;    /*     * Algorithm to find out if wheter or not any two     * given pair p-q is connected. It does not show     * how they are connected.     */    v_it start = id.begin( );    while( !queue.empty( ) )    {        std::pair<int,int> &pair = queue.front( );        int p = pair.first;        int q = pair.second;        int t = *(start+p);        if( t == *(start+q) )         {        }        else        {            for( v_it i = id.begin( ); i < id.end( ); i++ )             {                if( *(i) == t )                {                    *(i) = *(start+q);                }            }        }        std::cout << p <<   << q << \t;        copy( &id[0], &id[N], output_data( std::cout,   ) );        std::cout << std::endl;        queue.pop( );    }}The output and arguments to gcc would look like this:[mehoggan@desktop robert_sedgewick]$ g++ -o qf -Wall ./quick_find.cpp [mehoggan@desktop robert_sedgewick]$ ./qf p q   0 1 2 3 4 5 6 7 8 9 ------------------------------------3 4   0 1 2 4 4 5 6 7 8 9 4 9   0 1 2 9 9 5 6 7 8 9 8 0   0 1 2 9 9 5 6 7 0 9 2 3   0 1 9 9 9 5 6 7 0 9 5 6   0 1 9 9 9 6 6 7 0 9 2 9   0 1 9 9 9 6 6 7 0 9 5 9   0 1 9 9 9 9 9 7 0 9 7 3   0 1 9 9 9 9 9 9 0 9 4 8   0 1 0 0 0 0 0 0 0 0 5 6   0 1 0 0 0 0 0 0 0 0 0 2   0 1 0 0 0 0 0 0 0 0 6 1   1 1 1 1 1 1 1 1 1 1
Print pair representing objects from sequence of nonnegative integer pairs
c++;interview questions;mathematics;graph
I have a few more comments. I think you had a good idea adding typedefs to keep some of the names shorter and more meaningful, but I think I'd add even more than that.typedef std::ostream_iterator<int> output_data;typedef std::vector<int> graph;// As Martin said, `typename` isn't required (or really even allowed) here.typedef graph::iterator v_it; typedef std::pair<int, int> dt;Since you have code to show p, q and id in a couple of different places, and it's important that they match up with each other, I'd move that into a little function named display or something on that order. In one place, you need to display the names p and q, and in others their values, so we want to make this a template parameterized on the types of p and q:template <class T>void display(T p, T q, graph const &id) {     std::cout << p <<   << q << \t;    std::copy( id.begin( ), id.end( ), output_data( std::cout,   ) );    std::cout << '\n';}For example, when we use this from main to display the initial state, we use code something like this:display('p', 'q', id);std::cout << std::string(N*3, '-') << \n;As a general rule, I prefer to create a vector already initialized, rather than creating, then filling it with data. Since filling a vector (or whatever) with a sequence of values is something that comes up all the time, I have a sequence class and gen_seq front end for exactly that purpose. It would probably be overkill to write gen_seq just for this purpose, but I think it's worth having around anyway, and when you do, you might as well use it. The header looks like this:#ifndef GEN_SEQ_INCLUDED_#define GEN_SEQ_INCLUDED_template <class T>class sequence : public std::iterator<std::forward_iterator_tag, T>{     T val;public:    sequence(T init) : val(init) {}    T operator *() { return val; }    sequence &operator++() { ++val; return *this; }    bool operator!=(sequence const &other) { return val != other.val; }};template <class T>sequence<T> gen_seq(T const &val) {    return sequence<T>(val);}#endifWith this, you can create and initialize id like this: #include gen_seqgraph id(gen_seq(0), gen_seq(N));I also keep a couple of macros around that are handy when you're initializing a vector from an array. There are templates that are (at least theoretically) better, but I've never quite gotten around to switching over to them. The macros look like this:#define ELEMENTS_(x) (sizeof(x)/sizeof(x[0]))#define END(array) ((array)+ELEMENTS_(array))With these, the typedefs above, and (as sort of suggested by @Nim) using a vector instead of a queue, initializing your test data looks like this:dt pairs[] = {     dt( 3,4 ), dt( 4,9 ), dt( 8,0 ), dt( 2,3 ), dt( 5,6 ), dt( 2,9 ),     dt( 5,9 ), dt( 7,3 ), dt( 4,8 ), dt( 5,6 ), dt( 0,2 ), dt( 6,1 )};std::vector<dt> data((pairs), END(pairs));Instead of putting all the code to process the nodes into main, I'd move most of it out to a process_node function object. I'd also note that this:       for( v_it i = id.begin( ); i < id.end( ); i++ )         {            if( *(i) == t )            {                *(i) = *(start+q);            }        }...is essentially the same as std::replace(id.begin(), id.end(), t, *(start+q));. Taking that into account, process_node comes out looking something like this:class process_node {     graph &id;public:     process_node(graph &id) : id(id) {}    void operator()(dt const &pair) {         int p = pair.first;        int q = pair.second;        int o = id[p];        int n = id[q];        if(o != n)             std::replace(id.begin(), id.end(), o, n);        display(p, q, id);    }};Since we now have a vector to iterate through, and a function object to process each item, we can switch from an explicit loop to a standard algorithm:std::for_each(data.begin(), data.end(), process_node(id));[...and yes, for those find that unusual, this is a noteworthy day: I actually used std::for_each -- truly a rarity. ]That, however, brings up another point: there are still a few things about this code that don't excite me much. One, in particular, is that fact that it combines processing a node with displaying a row of results. We'd have to do a fair amount of extra work to avoid that, so I haven't bothered, but if we fixed that, std::for_each probably wouldn't be the right choice any more.