-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.cpp
248 lines (241 loc) · 12.6 KB
/
main.cpp
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#include <chrono>
#include <iostream>
#include <string>
#include "Database.h"
#include "MergeSort.h"
#include "BucketSort.h"
#include "PatienceSort.h"
#include "PatienceSortDate.h"
using namespace std;
int main() {
const string fileLocation = "parking_citations.csv";
Database database;
database.readFromCsv(fileLocation);
// NOTE: The parsed data is in vector form at database.data.
// Access it by doing *(database.data.at(index))
// If passing into a function, remember to pass by REFERENCE. Otherwise the code will be *very* slow.
//cout << "Removing all but the first 10000 elements..." << endl;
//database.data.erase(database.data.begin() + 8, database.data.end());
cout << "Welcome to No Parking (version 1.0)" << endl;
cout << "Type \"help\" for help" << endl;
while (true) {
string inputLine;
cout << endl << "Sorted by: " << database.getSortStatusString() << " >"; // Terminal prompt
getline(cin, inputLine);
// If there is one argument, lastArgument is the one that will be populated
// If there are two arguments, both middleArgument and lastArgument are populated
string command;
string firstArgument;
string secondArgument;
if (inputLine.find(' ') == string::npos) {
// No arguments.
command = inputLine.substr(0, inputLine.find(' '));
}
else if (inputLine.find_first_of(' ') == inputLine.find_last_of(' ')) {
// 1 argument.
command = inputLine.substr(0, inputLine.find(' '));
firstArgument = inputLine.substr(inputLine.find(' '));
firstArgument.erase(firstArgument.find(' '), 1);
}
else {
// 2 arguments
command = inputLine.substr(0, inputLine.find(' '));
firstArgument = inputLine.substr(inputLine.find(' '), inputLine.find_last_of(' ') - inputLine.find(' '));
firstArgument.erase(firstArgument.find(' '), 1);
secondArgument = inputLine.substr(inputLine.find_last_of(' '));
secondArgument.erase(secondArgument.find(' '), 1);
}
if (command.empty()) {
cout << "Please enter a command. Type \"help\" for help" << endl;
}
else if (command.at(0) == 'f') {
// find
if (firstArgument.empty()) {
cout << "Command \"find\" requires one argument <query>." << endl;
}
else {
auto startTime = chrono::system_clock::now(); // Get start time
int index = database.binarySearch(firstArgument);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
if (index == -2) {
cout << "Cannot run command \"find\" before sorting input" << endl;
}
else if (index == -1) {
cout << "No results for query \"" << firstArgument << "\"" << endl;
}
else {
cout << "Found results at index " << std::to_string(index) << endl;
// Print ALL elements that match the query.
if (database.sortStatus == Database::SORT_PLATES) {
int currentlyPrinting = index;
while (currentlyPrinting >= 0 && database.data.at(currentlyPrinting)->plateNumber == firstArgument) {
cout << (std::string) *database.data.at(currentlyPrinting) << endl;
currentlyPrinting--;
}
currentlyPrinting = index + 1;
while (currentlyPrinting < database.data.size() && database.data.at(currentlyPrinting)->plateNumber == firstArgument) {
cout << (std::string) *database.data.at(currentlyPrinting) << endl;
currentlyPrinting++;
}
}
else if (database.sortStatus == Database::SORT_DATE) {
// Print dates in order by finding the first matching date and iterating until the last date.
int currentlyPrinting = index;
while (true) {
if (currentlyPrinting == 0) {
break;
}
else if (database.data.at(currentlyPrinting - 1)->dateTime->getDateString() == firstArgument) {
currentlyPrinting--;
}
else {
break;
}
}
while (currentlyPrinting < database.data.size() && database.data.at(currentlyPrinting)->dateTime->getDateString() == firstArgument) {
cout << (std::string) *database.data.at(currentlyPrinting) << endl;
currentlyPrinting++;
}
}
}
if (index != -2) {
cout << "The binary search took " << elapsedTime.count() << " seconds." << endl;
}
}
}
else if (command.at(0) == 'g') {
// get
int indexToGet = 0; // The index to get
try {
// Parse the argument as an integer
indexToGet = std::stoi(firstArgument);
if (indexToGet < 0) {
cout << "Expected <index> in get command to be positive, got " << firstArgument << endl;
continue;
}
else if (indexToGet >= database.data.size()) {
cout << "Cannot get index " << firstArgument << " in array of size " << database.data.size() << endl;
continue;
}
}
catch (std::invalid_argument &e) {
cout << "get command requires an integer as the first argument, not \"" << firstArgument << '\"' << endl;
continue;
}
cout << (string) *database.data.at(indexToGet) << endl;
}
else if (command.at(0) == 'l') {
// linear search
if (firstArgument.empty()) {
cout << "Command \"lfind\" requires one argument <query>." << endl;
}
else {
cout << "Linear searching for license plate \"" << firstArgument << "\"..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
int index = database.linearSearchLicensePlate(firstArgument);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
if (index != -1) {
cout << (std::string) *database.data.at(index) << endl;
}
else {
cout << "License plate \"" << firstArgument << "\" not found" << endl;
}
cout << "The linear search took " << elapsedTime.count() << " seconds." << endl;
}
}
else if (command.at(0) == 'q') {
// quit
break;
}
else if (command.at(0) == 'r') {
// reload
database.data.clear(); // Empty the database.
database.readFromCsv(fileLocation); // Reread data from CSV
database.sortStatus = Database::SORT_UNSORTED; // Mark as unsorted
cout << "Successfully reloaded data from disk" << endl;
}
else if (command.at(0) == 's') {
// sort
if (firstArgument.empty()) {
cout << "Command \"sort\" requires one argument <algorithm>, which can be m for merge, b for bucket, or p for patience." << endl;
}
else if (firstArgument.at(0) == 'm') {
if (!secondArgument.empty() && secondArgument.at(0) == 'd') {
cout << "Now merge sorting by date..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
MergeSort::mergeSortDates(database.data);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
cout << "Took " << elapsedTime.count() << " seconds to sort." << endl;
database.sortStatus = Database::SORT_DATE;
}
else {
cout << "Now merge sorting by license plate..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
MergeSort::mergeWrapper(database.data);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
cout << "Took " << elapsedTime.count() << " seconds to sort." << endl;
database.sortStatus = Database::SORT_PLATES;
}
}
else if (firstArgument.at(0) == 'b') {
if (!secondArgument.empty() && secondArgument.at(0) == 'd') {
cout << "Now bucket sorting by date..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
BucketSort::bucketSortDateWrapper(database.data);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
cout << "Took " << elapsedTime.count() << " seconds to sort." << endl;
database.sortStatus = Database::SORT_DATE;
}
else {
cout << "Now bucket sorting by license plate..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
BucketSort::bucketSortWrapper(database.data);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
cout << "Took " << elapsedTime.count() << " seconds to sort." << endl;
database.sortStatus = Database::SORT_PLATES;
}
}
else if (firstArgument.at(0) == 'p') {
if (!secondArgument.empty() && secondArgument.at(0) == 'd') {
cout << "Now patience sorting by date..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
PatienceSortDate::patienceSort(database.data);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
cout << "Took " << elapsedTime.count() << " seconds to sort." << endl;
database.sortStatus = Database::SORT_DATE;
}
else {
cout << "Now patience sorting by license plate..." << endl;
auto startTime = chrono::system_clock::now(); // Get start time
PatienceSort::patienceSort(database.data);
auto endTime = chrono::system_clock::now(); // Get end time
std::chrono::duration<double> elapsedTime = endTime - startTime;
cout << "Took " << elapsedTime.count() << " seconds to sort." << endl;
database.sortStatus = Database::SORT_PLATES;
}
}
else {
cout << "Please type m for merge sort, b for bucket sort, or p for patience sort." << endl;
}
}
else {
// help
cout << "Commands list:" << endl;
cout << "find <query> - Performs binary search for a parking citation" << endl;
cout << "get <index> - Gets the parking citation at a specific index" << endl;
cout << "help - Displays this help message" << endl;
cout << "lfind <query> - Performs linear search for a license plate number" << endl;
cout << "reload - Reloads the database from file" << endl;
cout << "quit - Exits the program" << endl;
cout << "sort <algorithm> <field> - Sorts citations. Algorithm is m for merge sort, \n" <<
"b for bucket sort, or p for patience sort. Field can be l for license plates or d for dates." << endl;
}
}
}