Finding consecutive numbers in a vector I need to write a program to print the line numbers, in ascending order, of a particular word in a file. Example output of the program would be:

 Hello 1, 3, 5-6, 8, 10-15.
// 5-6 represents 5, 6 (consecutive numbers)


The line numbers are stored in a sorted vector&lt;int&gt; with no duplicates. I have created a solution, but my instincts tell me I can do better. I would appreciate some feedback. Further, the following code only processes the line numbers; the word is found in another method. I will remark that intToString() is a custom method that does as the name implies. It returns a static string.

void IndexPager::createLines(vector&lt;int&gt;&amp; vec, string&amp; line)
{
  int start = *vec.begin(), end = -1, offset = 0; // initial offset to start

  for (vector&lt;int&gt;::const_iterator itr = vec.begin();
       itr != vec.end() + 1; itr++)
  {
    if (*itr == start + offset &amp;&amp; itr != vec.end())
    {
      end = *itr;
      ++offset;
    } // check if line numbers are consecutive and not reading at end of vector
    else // not consecutive
    {
      if ((end != -1) &amp;&amp; (end != start))
      {
        line.append(intToString(start) + "-");
        line.append(intToString(end));
      } // if there existed consecutive numbers, display with dash
        // must be difference of at least 1
      else // else, there were no consecutive numbers
        line.append(intToString(start));

      if (itr != vec.end()) // check if not at end of vector
        line.append(", ");
      else // reached end of vector
        line.append(".");

      start = *itr; // set start to next line number. Soft reset.
      offset = 1; // change default offset to 1. 0 for first case.
      end = -1;
    } // not consecutive
  } // Get all line numbers and format for proper output
} // createLines()
First use ++it instead it++ with iterators.
You can replace this loop:

for (vector&lt;int&gt;::const_iterator itr = vec.begin();
     itr != vec.end() + 1; itr++)`


with range-based for:

for (auto i : v)

vec.end() returns iterator representing element after the last element in vector
if (itr != vec.end()) loop also does this check
I think you can rewrite your code to be clearer and with less ifs
also you can use std::to_string instead of intToString
also if you want to append . at the end of string you can do it outside of the loop




Here is the code with few things fixed; still I think you can do even better than that if you rethink your conditions.

void createLines(vector&lt;int&gt;&amp; vec, string&amp; line)
{
  int start = *vec.begin(), end = -1, offset = 0; // initial offset to start

  for (auto i : vec)
  {
    if (i == start + offset)
    {
      end = i;
      ++offset;
    } // check if line numbers are consecutive and not reading at end of vector
    else // not consecutive
    {
      if ((end != -1) &amp;&amp; (end != start))
      {
        line.append(to_string(start) + "-");
        line.append(to_string(end));
      } // if there existed consecutive numbers, display with dash
        // must be difference of at least 1
      else // else, there were no consecutive numbers
        line.append(to_string(start));

    line.append(", ");

  start = i; // set start to next line number. Soft reset.
  offset = 1; // change default offset to 1. 0 for first case.
  end = -1;
} // not consecutive
} // Get all line numbers and format for proper output
 if ((end != -1) &amp;&amp; (end != start))
 {
   line.append(to_string(start) + "-");
   line.append(to_string(end));
 } 
 else
   line.append(to_string(start));
line.append(".");
} // createLines()