-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsmarter_queue_lib.cc
131 lines (118 loc) · 3.18 KB
/
smarter_queue_lib.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "smarter_queue.hh"
#include <cassert>
#include <cerrno>
using namespace std;
namespace smarter_queue {
ostream &operator<<(ostream &out, const SmarterQueue &sq) {
for (int i = 0; i < sq.size_; i++) {
out << sq.data_[i] << " ";
}
return out;
}
pair<int, SmarterQueue> SmarterQueue::operator()(int begin, int end) {
pair<int, SmarterQueue> result;
if ((begin < 0) || (end > (size_ - 1)) || (begin > end)) {
cerr << "Limits are out of bounds." << endl;
return make_pair<int, SmarterQueue>(ERANGE, SmarterQueue());
}
vector<double> vec;
for (int i = begin; i <= end; i++) {
vec.push_back(data_[i]);
}
return make_pair<int, SmarterQueue>(0, SmarterQueue(vec));
}
bool operator==(const SmarterQueue &sq1, const SmarterQueue &sq2) {
if (sq1.size_ != sq2.size_) {
return false;
}
for (int i = 0; i < sq1.size_; i++) {
if (sq1.data_[i] != sq2.data_[i]) {
return false;
}
}
return true;
}
void SmarterQueue::Push(double dat) {
if (is_full()) {
cerr << "Queue is already full." << endl;
return;
}
if (writer_cursor_ == size_) {
cout << "Shifting queue." << endl;
for (int i = reader_cursor_; i < size_; i++) {
data_[i - reader_cursor_] = data_[i];
}
reader_cursor_ = 0;
return;
}
data_[writer_cursor_++] = dat;
}
pair<int, double> SmarterQueue::Pop() {
if (is_empty()) {
return pair<int, double>(ENODATA, 0.0);
}
return pair<int, double>(0, data_[reader_cursor_++]);
}
pair<int, double> SmarterQueue::Peek(const int offset) const {
if (is_empty()) {
return pair<int, double>(ENODATA, 0.0);
}
const int index = reader_cursor_ + offset;
if ((size_ <= index) || (offset < 0)) {
return pair<int, double>(ERANGE, 0.0);
}
return pair<int, double>(0, data_[index]);
}
// Pass the argument by value to avoid const-conversion with the iterator.
bool SequenceIsIncreasing(vector<double> vec) {
if (vec.empty() || (1 == vec.size())) {
return true;
}
double last = vec.front();
for (vector<double>::iterator it = vec.begin(); it < vec.end(); it++) {
if ((*it) < last) {
return false;
}
last = *it;
}
return true;
}
int FindIncreasingSubsequences(ostream &out, const SmarterQueue &sq) {
if (sq.is_empty()) {
return 0;
}
int offset = 0;
out << "(";
vector<double> vec;
while (offset < sq.size()) {
// This code is unreachable.
// int retval = 0;
// if ((retval = sq.Peek(offset).first) != 0) {
// return retval;
// }
double save;
// Save the increasing subsequences in a vector.
vec.push_back(sq.Peek(offset).second);
if (!SequenceIsIncreasing(vec)) {
// Putting decreasing element back on FIFO Queue doesn't work, since
// reader and writer are at different ends by design.
// sq1.Push(vec.pop_back());
// Remove and save the decreasing element.
save = vec.back();
vec.pop_back();
out << vec;
out << "), (";
// Start next iteration with decreasing element.
vec.clear();
vec.push_back(save);
}
offset++;
}
// Make sure last element gets printed.
if (!vec.empty()) {
out << vec;
out << ")";
}
return 0;
}
} // namespace smarter_queue