forked from Dennis-ty/cs110ProjectC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProjectCPartBDriver.java
207 lines (183 loc) · 8.58 KB
/
ProjectCPartBDriver.java
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
import java.io.*;
import java.text.*;
import java.util.*;
import java.time.*;
public class ProjectCPartBDriver {
// adjust how many reports you read in- lower the maxNumberReports if your machine is taking too long!
// set useAllReports to false if you want to read in the whole data file
// if use all the reports, set runComparisonC to false or else you'll be waiting a long time!
private static boolean useAllReports = false;
private static int maxNumberReports = 40000;
private static boolean runTestB = true; // should be false if useAllReports=true!
public static void main(String[] args) throws IOException, ParseException {
List<PoliceReport> reportList = readList();
BinarySearchTreeWithDups<PoliceReport> reportTree;
System.out.println("------------------------------TEST A: TREE BUILT FROM A SORTED LIST, ASCENDING------------------------------");
Collections.sort(reportList);
reportTree = buildTreeFromList(reportList);
processTree(reportTree);
if(!useAllReports && runTestB) {
System.out.println("\n\n------------------------------TEST B: TREE BUILT FROM A SORTED LIST, DESCENDING------------------------------");
Collections.sort(reportList);
Collections.reverse(reportList);
reportTree = buildTreeFromList(reportList);
processTree(reportTree);
} else if(useAllReports && runTestB) {
System.out.println("\n\n------------------------------TEST B: TREE BUILT FROM A SORTED LIST, DESCENDING------------------------------");
System.out.println("***TEST B canceled. I strongly recommend that you set useAllReports to false in order to run Test B!");
}
System.out.println("\n\n------------------------------TEST C: TREE BUILT FROM A SHUFFLED LIST------------------------------");
Collections.shuffle(reportList);
reportTree = buildTreeFromList(reportList);
processTreeAndList(reportTree, reportList);
System.out.println("\n\n------------------------------EXTRA CREDIT TEST: COUNT OF UNIQUE VALUES------------------------------");
System.out.println("Unique Values: ");
if(!useAllReports) {
if(maxNumberReports!=40000) {
System.out.println("***ERROR! This test assumes maxNumberReports=40000, not " + maxNumberReports);
System.out.println(" Change this in line 12 in order to use this test.");
} else {
System.out.println("Expected=" + 4664);
System.out.println(" Actual=" + reportTree.countUniqueValues());
}
} else {
System.out.println("Expected=" + 4681);
System.out.println(" Actual=" + reportTree.countUniqueValues());
}
}
private static void processTree(BinarySearchTreeWithDups<PoliceReport> tree) {
processTreeAndList(tree, null);
}
private static void processTreeAndList(BinarySearchTreeWithDups<PoliceReport> tree, List<PoliceReport> list) {
boolean printList = list==null ? false : true;
if(printList) {
System.out.println("Processing tree and list...");
} else {
System.out.println("Processing tree...");
}
long elapsedTimeTree = 0, elapsedTimeList = 0;
// these represent the earliest date, latest date, two dates in the middle, a high-frequency date, and two dates not in the set
String[] dateStrings = {"01/1/2003", "10/27/2015", "10/02/2009", "03/23/2010", "03/28/2015", "11/9/2018", "11/9/2000"};
for (String date : dateStrings) {
PoliceReport dummyReport = new PoliceReport();
dummyReport.setDate(date);
Instant start = Instant.now();
int reportCountTree = tree.countIterative(dummyReport);
long oneTimeTree = Duration.between(start, Instant.now()).toMillis();
elapsedTimeTree += oneTimeTree;
start = Instant.now();
long reportCountList = 0L;
if(printList) {
reportCountList = list.stream().filter(report -> report.isOnDate(date)).count();
/* the above is code that uses Java 8 streams (which we do not cover)
* here is what the non-stream code would look like:
long reportCountL = 0;
for(PoliceReport report : list) {
if(report.isOnDate(date)) {
reportCountL++;
}
}
*/
}
long oneTimeList = Duration.between(start, Instant.now()).toMillis();
elapsedTimeList += oneTimeList;
System.out.print("\tIncident Date: " + date);
System.out.print("\tNumber of Incidents: " + reportCountTree);
System.out.print("\tTree Time: " + oneTimeTree);
if(printList) {
System.out.println(" List Time: " + oneTimeList);
} else {
System.out.println();
}
}
System.out.println("Processing complete. ");
System.out.print("Total Time Required: Tree: " + elapsedTimeTree);
if(printList) {
System.out.println(" List: " + elapsedTimeList);
System.out.print((Long.compare(elapsedTimeTree,elapsedTimeList)<0 ? "Tree was faster." : "List was faster."));
} else {
System.out.println();
}
}
private static List<PoliceReport> readList() throws IOException {
List<PoliceReport> masterReportList = new ArrayList<>();
String fileName = "SFPD_Incidents_TheftLarceny.csv";
Scanner fileScan = new Scanner(new File(fileName));
fileScan.nextLine(); // read the column headers
int numRecordsReadIn = 0;
while (fileScan.hasNextLine() &&
(useAllReports || (!useAllReports && numRecordsReadIn<maxNumberReports)) ){
numRecordsReadIn++;
String singleReport = fileScan.nextLine();
Scanner reportScan = new Scanner(singleReport);
reportScan.useDelimiter(",");
// this code assumes the file is perfectly formatted- it does not
// account for errors in formatting
PoliceReport report = new PoliceReport(
Long.parseLong(reportScan.next()), // incident number
reportScan.next(), // category
reportScan.next(), // description
reportScan.next(), // day
reportScan.next(), // date
reportScan.next(), // district
reportScan.next(), // resolution
reportScan.next() // address
);
masterReportList.add(report);
}
return masterReportList;
}
private static BinarySearchTreeWithDups<PoliceReport> buildTreeFromList(List<PoliceReport> list) {
Instant start = Instant.now();
BinarySearchTreeWithDups<PoliceReport> reportTree = new BinarySearchTreeWithDups<PoliceReport>();
int count = 0;
for (PoliceReport report : list) {
reportTree.add(report);
count++;
if (count % 10000 == 0) {
System.out.println("\t...building tree with entry " + count);
}
}
long elapsedTime = Duration.between(start, Instant.now()).toMillis();
System.out.println("Time required to build tree: " + elapsedTime + " milliseconds");
System.out.println("Tree Info:");
System.out.println("\tRoot is " + reportTree.getRootData());
try {
System.out.println("\tNumber of nodes: " + reportTree.root.getNumberOfNodes());
} catch(StackOverflowError ex) {
System.out.println("\tNumber of nodes: ***Cannot find the number of nodes! Stack overflow.");
}
System.out.println("\tNumber of nodes equal to the root: " + reportTree.countIterative(reportTree.root.getData()));
System.out.println("\tNumber of nodes bigger than root: " + reportTree.countGreaterIterative(reportTree.getRootData()));
if(reportTree.root.hasLeftChild()) {
try {
System.out.println("\tNumber of nodes in left subtree: " + reportTree.root.getLeftChild().getNumberOfNodes());
} catch(StackOverflowError ex) {
System.out.println("\tNumber of nodes in left subtree: ***Cannot find the number of nodes in the left subtree! The left subtree was too deep and it caused a stack overflow.");
}
} else {
System.out.println("\tNumber of nodes in left subtree: 0");
}
if(reportTree.root.hasRightChild()) {
try {
System.out.println("\tNumber of nodes in right subtree: " + reportTree.root.getRightChild().getNumberOfNodes());
} catch(StackOverflowError ex) {
System.out.println("\tNumber of nodes in right subtree: ***Cannot find the number of nodes in the right subtree! The right subtree was too deep and it caused a stack overflow.");
}
} else {
System.out.println("\tNumber of nodes in right subtree: 0");
}
try {
System.out.println("\tLeft height: " + reportTree.getLeftHeight());
} catch(StackOverflowError ex) {
System.out.println("\tLeft height: ***Cannot find the left height! Left subtree is too deep and it caused a stack overflow.");
}
try {
System.out.println("\tRight height: " + reportTree.getRightHeight());
} catch(StackOverflowError ex) {
System.out.println("\tRight height: ***Cannot find the right height! Right subtree too deep and it caused a stack overflow.");
}
System.out.println("Tree build and report complete!\n");
return reportTree;
}
}