Pairwise Hamming Distance
Code Review

Never use C cast

The C cast is dangerously hard to spot. In C++ we have replaced this with four distinct cast operators that all do slightly different things. They are very easy to spot (as you should not really be doing cast anyway and when you do we want to be able to spot it easily for code review).

            bin.push_back((char)('0'));


So if this was C++ that would use the static cast.

            bin.push_back(static_cast&lt;char&gt;('0'));


But not really. Anything that is in single quotes '0' already has a type of char so you don't actually need to cast it.

            bin.push_back('0');


Also in this situation. you only push back one character. So why not just use assignment in the first place.

            bin = "0"; // much more clear.


Actually there is no need to even use the variable bin. In the next line you can simply push back a literal string.

            binrep.push_back(bin);

            // why not just
            binrep.push_back("0");


Use C++ classes where you can.

        while (n &gt; 0) {
            rem = n % 2; 
            bin.push_back((char)('0' + rem));
            n /= 2;
        }


So you are building a binary version of the number in a string. Easier way to do that using std::bitset.

        std::bitset&lt;8&gt; value(n);
        bin.push_back(value.to_string()); // You may need to reverse
                                          // or something I did not pay
                                          // full attention to what you
                                          // were doing.


When looping over containers use the range based for.

    for(i=0;i&lt;N;i++){

    // can be replaced by this.
    for(auto const&amp; item: binrep) {


Look for standard algorithms where you have a loop:

This looks like you are counting.

                while (binrep[j][k] !='\0'){
                    if(binrep[j][k]=='1')
                        count++;
                    k++;
                } 

                // I think it may have been easier to write:
                count += std::count(std::begin(binrep[j]), std::end(binrep[j]), '1');


This is also self documenting as you can see what you are doing. The algorithm is appropriately named to make your actions obvious.

###BUG

            binrep[i][k] != '\0'


You can not look for a terminating \0 on a C++ std::string. Accessing beyond the end of the string is undefined behavior. If you want a C-String version to loop over you need to call c_str() on the object (but better to use a range based for.

Style

A lot of this (style) is preference and dependent on your team. I think it is important for the community to be consistent and have describes some common practices below. Others will inevitably disagree as this is opinion, refer to your teams style guide.

But your horizontal spacing (it does not exist) makes your code hard to read it is all packed together horizontally. It just makes the code horrible (and thus harder to read). Technically nothing wrong with that, but the whole point of coding is to make it easy to read for the next human that has to decipher your code.

for(i=0;i&lt;N;i++){

// I would write it like this:

for(int i = 0; i &lt; N; ++i) {


Your usage of braces ( {} ) is inconsistent. Neither version is wrong. But using two different styles is jarring (and again makes it hard to read).

        while (n &gt; 0) {
            // STUFF
        }

   // and

        while (binrep[i][k] != '\0' &amp;&amp; binrep[j][k] !='\0')
        {
        }


Always indent sub-blocks and always use braces {} around sub blocks.

        // Not indenting the sub block makes it hard to read.
        while (n &gt; 0) {
        rem = n % 2; 
        bin.push_back((char)('0' + rem));
        n /= 2;
        }

        // Not using braces opens you up to maintenance problems.
        // larger than needed modifications when a bug is fixed.
        // thus reduced readability in the change log.
        //
        // There are also corner cases that are going where not
        // using the braces are going to be an error so prefer
        // to use them.
        if (binrep[i][k] != binrep[j][k])
            count++;


Declare variables one per line and at the point where they are used. This makes it easier to check types of local objects, and becomes much more important when your types have constructors and  destructors.

    // Also the inconsistent use of space is jarring.
    int i,j, rem, n;


Variable names. Please use them. Modern code is supposed to be self documenting. So reading the variable name and how it is used is supposed to help me to understand the context of the code.

    // I have no idea what these do (rem: short for remainder?)
    int i,j, rem, n;


    for(int loop = 0; loop &lt; size; ++loop) // Its a loop.


With naming. It's traditional to use an initial upper case letter for user defined types while an initial lower case letter is used for objects (variables/functions). This is important in C++ because types are so much more important than in C. We want to understand when we are referring to a user type and when we are referring to an object (the distinction is important and the use of visual cues can help make the code self documenting).

NOTE: The use of identifiers that are all uppercase is still (even in C++) traditionally reserved for macros. You should avoid their use for other things. N is an all uppercase identifier.

Pick a style and be consistent. Consistency is key in making code that is easy to maintain.