cprover
format_number_range.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Format vector of numbers into a compressed range
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include <algorithm>
13 #include <cassert>
14 #include <string>
15 
16 #include "format_number_range.h"
17 
21 std::string format_number_range(std::vector<unsigned> &numbers)
22 {
23  std::string number_range;
24  std::sort(numbers.begin(), numbers.end());
25  unsigned end_number=numbers.back();
26  if(numbers.front()==end_number)
27  number_range=std::to_string(end_number); // only single number
28  else
29  {
30  bool next=true;
31  bool first=true;
32  bool range=false;
33  unsigned start_number=numbers.front();
34  unsigned last_number=start_number;
35 
36  for(const auto &number : numbers)
37  {
38  if(next)
39  {
40  next=false;
41  start_number=number;
42  last_number=number;
43  }
44  // advance one forward
45  else
46  {
47  if(number==last_number+1 && !(number==end_number))
48  {
49  last_number++;
50  if(last_number>start_number+1)
51  range=true;
52  }
53  // end this block range
54  else
55  {
56  if(first)
57  first=false;
58  else
59  number_range+=",";
60  if(last_number>start_number)
61  {
62  if(range)
63  {
64  if(number==end_number && number==last_number+1)
65  number_range+=
66  std::to_string(start_number)+"-"+std::to_string(end_number);
67  else if(number==end_number)
68  number_range+=
69  std::to_string(start_number)+"-"+std::to_string(last_number)+
70  ","+std::to_string(end_number);
71  else
72  number_range+=
73  std::to_string(start_number)+"-"+std::to_string(last_number);
74  }
75  else
76  {
77  if(number!=end_number)
78  number_range+=
79  std::to_string(start_number)+","+std::to_string(last_number);
80  else
81  {
82  if(start_number+1==last_number && last_number+1==number)
83  number_range+=
84  std::to_string(start_number)+"-"+std::to_string(end_number);
85  else
86  number_range+=
87  std::to_string(start_number)+
88  ","+std::to_string(last_number)+
89  ","+std::to_string(end_number);
90  }
91  }
92  start_number=number;
93  last_number=number;
94  range=false;
95  continue;
96  }
97  else
98  {
99  if(number!=end_number)
100  number_range+=std::to_string(start_number);
101  else
102  number_range+=std::to_string(start_number)+","+
103  std::to_string(end_number);
104  start_number=number;
105  last_number=number;
106  range=false;
107  continue; // already set next start number
108  }
109  next=true;
110  }
111  }
112  }
113  }
114  assert(!number_range.empty());
115  return number_range;
116 }
std::string format_number_range(std::vector< unsigned > &numbers)
create shorter representation for output
std::string to_string(const string_constraintt &expr)
Used for debug printing.
Format vector of numbers into a compressed range.