c++ - Getting range of numbers from a (sorted) list of numbers -


i came across following problem: consider having ascending list of numbers (e.g. 1,2,3,7,8,10), gather ranges (of consecutive numbers) , print them in compact form (with numbers given above):

1->3 7->8 10

in particular, solution should work "degenerated cases" list of 1 element, or list -2,1.

i came solution, tried separate numbers different vectors, looks quite cumbersome. so, know if there better alternative approach problem.

here approach:

vector< vector<int> > result(numbers.size()*numbers.size(), vector<int>());  int last_range; vector<int> range; vector<string> result_string;  //1,2,3,7,8,10  if(numbers.size() == 1)  {     stringstream ss;       ss << numbers[0];      result_string.push_back(ss.to_string());      return result_string;  }   (int = 1; < numbers.size(); i++ ) {      if( numbers[i] - numbers[i-1] == 1 )      {         range.push_back(numbers[i]);     }      if ( == numbers.size()-1 )      {         last_range = numbers[i];         range.push_back(last_range);     }      result[i-1].push_back(range); }   if( result.size() < 1 ) {     range.push_back(numbers[0]);      result[0].push_back(range);      stringstream ss;      ss << result[0][0];      result_string.push_back(ss.to_string());      return result_string; }  //result[0] - > array of numbers  1,2,3  // result [1] - > array of numbers   (int = 0; < result.size(); i++ ) {         int start_index = result[i][0];         int last_index  = result[i][result.size()-1];           stringstream ss_startindex;          stringstream ss_endindex;           ss_startindex << result[i][0];         ss_endindex  << result[i][result.size()-1];         string result = ss_startindex.to_string() + "->" + ss_endindex.to_string();         result_string.push_back(result);  }         return result_string; } 

what need object carries context ('next integer part of range?') across, while iterate on sequence. kind of problem best solved function object used unary function std::for_each algorithm.

a working example be:

#include <algorithm> #include <limits> #include <utility> #include <vector>  #include <iostream>  using intcollection = std::vector<int>;  intcollection = {1,2,3,7,8,10}, is2 = {-2,1}, is3 = {20};  using range = std::pair<int,int>;  class intrangeprinter { public:     void operator() (int i)     {         if (r.first == inval)             r.first = i;         else if (r.second == inval && r.first + 1 == i)             r.second = i;         else if (r.second + 1 == i)             r.second = i;         else {             print_range_or_value();             // reset after printing             reset();             // , re-init range current value             r.first = i;         }     }      // there might "pending" data printed     void flush()     {         print_range_or_value();         std::cout << std::endl;         reset();     }  private:     static int inval; // value not expected in intcollection     void print_range_or_value()     {         if (r.first != inval && r.second != inval)             std::cout << ' ' << r.first << "->" << r.second;         else // if (r.second == inval)             std::cout << ' ' << r.first;     }     void reset ()     {         r.first = inval;         r.second = inval;     }      range r = {inval,inval};  };  int intrangeprinter::inval = std::numeric_limits<int>::max();  int main () {     intrangeprinter p;     p = std::for_each(is.begin(), is.end(), std::move(p));     p.flush();      p = std::for_each(is2.begin(), is2.end(), std::move(p));     p.flush();      p = std::for_each(is3.begin(), is3.end(), std::move(p));     p.flush();      return 0; } 

Comments

Popular posts from this blog

PHP and MySQL WP -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

go - golang pprof for c library code -