Determining whether one vector is a prefix of the other I am learning from C++ Primer 5th edition. This is exercise 5.17:


  Given two vectors of ints, write a program to determine whether one vector is a prefix of the other. For vectors of unequal length, compare the number of elements of the smaller vector. For example, given the vectors containing 0, 1, 1, and 2 and 0, 1, 1, 2, 3, 5, 8, respectively your program should return true.


#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::end;
using std::begin;


int main()
{
    vector&lt;int&gt; i{0,1,1,2}, n{0,1,1,2,3,5,8}, smlr;
    char sml, bgr;
    long j = (i.end()-i.begin()) ,k = (n.end()-n.begin());
    if ( j &gt; k)
    {
        sml = 'n', bgr = 'i', smlr = n;
    }

    else if (j &lt; k)
    {
        sml = 'i', bgr = 'n', smlr = i;
    }
    else if ( j == k)
    {
        cout &lt;&lt; "both are of equal length";

        for (vector&lt;int&gt;::size_type a = 0; a &lt; i.size() ; ++a ) {
            if (i[a] != n[a]) {
                cout &lt;&lt; "both vectors are unequal and are not prefixes of the other";
                return -1;
            }
        }
    }

    for ( int l = 0; l &lt; smlr.size() &amp;&amp; i[l] == n[l]; ++l )
    {
            if(l == (smlr.size()-1))
            {
            cout &lt;&lt; sml &lt;&lt; " is a prefix of " &lt;&lt; bgr;
            return 0;
            }
    }
    cout &lt;&lt; sml &lt;&lt; " is not a prefix of " &lt;&lt; bgr;
    return 0;
}



Is my code efficient?
Am I using too many variables?
Is it better to write more code and use less variables or use less variables and less code?


I am a beginner, so please be harsh.
Ok first, we want to determine if some condition is true or not based on some input. That calls for a boolean function! In particular, our inputs are two vectors. :

bool isPrefixOf(const std::vector&lt;int&gt;&amp; smaller, const std::vector&lt;int&gt;&amp; larger) 
{
    ...
}


I named the first variable smaller, but it might not actually be smaller! Let's make sure that it is:

    if (smaller.size() &gt; larger.size())
    {
        std::swap(smaller, larger); // this very efficiently swaps our vectors
                                    // in constant time
    }


Now once we got that, the algorithm in your j == k is exactly correct, but pretty hard to read. The convention is to use variables like i, j, k solely as indices in loops, not as important variables. So I'll rewrite it like this:

    for (int i = 0; i &lt; smaller.size(); ++i) 
    {
        if (smaller[i] != larger[i]) 
        {
            return false; // clearly not a prefix
        }
    }

    return true; // we match up, so we must be done!
}


So cool, we got our function that checks if a smaller vector is a prefix of a larger vector, so now our main just has to determine which way we call it:

int main() 
{
    vector&lt;int&gt; vec1{0, 1, 1, 2};
    vector&lt;int&gt; vec2{0, 1, 1, 2, 3, 5, 8};

    cout &lt;&lt; "vec1 is a prefix of vec2?: " &lt;&lt; isPrefixOf(vec1, vec2) &lt;&lt; endl;
}


Which should print true. So in general, your variable names don't line up with convention, and you coded the same logic twice - don't repeat yourself! Take advantage of functions to encode conceptually distinct functionality.