-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPointST.java
152 lines (129 loc) · 5.34 KB
/
PointST.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
/* *****************************************************************************
* Description: This class implements the mutable data type PointST, which uses
* the RedBlackBST class to represent a symbol table whose keys are Points2D
* (2-dimensional points).
**************************************************************************** */
import edu.princeton.cs.algs4.Point2D;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.RectHV;
import edu.princeton.cs.algs4.RedBlackBST;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
public class PointST<Value> {
private final RedBlackBST<Point2D, Value> pts; // symbol table of 2D points
// construct an empty symbol table of points
public PointST() {
pts = new RedBlackBST<Point2D, Value>();
}
// is the symbol table empty?
public boolean isEmpty() {
return pts.isEmpty();
}
// number of points
public int size() {
return pts.size();
}
// associate the value val with point p
public void put(Point2D p, Value val) {
if (p == null || val == null)
throw new IllegalArgumentException("arguments cannot be null");
pts.put(p, val);
}
// value associated with point p
public Value get(Point2D p) {
if (p == null)
throw new IllegalArgumentException("argument cannot be null");
return pts.get(p);
}
// does the symbol table contain point p?
public boolean contains(Point2D p) {
if (p == null)
throw new IllegalArgumentException("argument cannot be null");
return pts.contains(p);
}
// all points in the symbol table
public Iterable<Point2D> points() {
return pts.keys();
}
// all points that are inside the rectangle (or on the boundary)
public Iterable<Point2D> range(RectHV rect) {
if (rect == null)
throw new IllegalArgumentException("argument cannot be null");
// enqueue points within/on the rectangle onto a queue using the
// contains() method supported by RectHV
Queue<Point2D> ptsInRange = new Queue<Point2D>();
for (Point2D pt : this.points()) {
if (rect.contains(pt))
ptsInRange.enqueue(pt);
}
return ptsInRange;
}
// a nearest neighbor of point p; null if the symbol table is empty
public Point2D nearest(Point2D p) {
if (p == null)
throw new IllegalArgumentException("argument cannot be null");
if (pts.isEmpty())
return null;
// iterate through all points, calculating distance to p and updating
// minimum distance found (as well as the point that gave this min)
double min = Double.POSITIVE_INFINITY;
Point2D closest = null;
for (Point2D pt : this.points()) {
double dist = p.distanceSquaredTo(pt);
if (dist < min) {
min = dist;
closest = pt;
}
}
return closest;
}
// unit testing
public static void main(String[] args) {
PointST<Double> st = new PointST<Double>();
// read in pairs of coordinates from StdIn and add to the symbol table
double val = 0.0; // initialize non-null values to associate with keys
while (!StdIn.isEmpty()) {
double x = StdIn.readDouble();
double y = StdIn.readDouble();
Point2D pt = new Point2D(x, y);
st.put(pt, val++); // val will increment by 1.0 per pair of coords
}
// print out all points
StdOut.println(st.points());
// get values associated with points: vals should correspond to the
// order in which the coordinates are listed in the input file
for (Point2D pt : st.points()) {
double valOut = st.get(pt);
StdOut.print(valOut + " ");
}
StdOut.println();
// print out whether st is empty
StdOut.println("st is empty: " + st.isEmpty());
// print out num of points
StdOut.println("# of points: " + st.size());
// generate a random point p and check if the st contains p
Point2D p = new Point2D(StdRandom.uniform(0.0, 1.0),
StdRandom.uniform(0.0, 1.0));
StdOut.println("generating random point p: " + p);
StdOut.println("st contains p: " + st.contains(p));
// find nearest neighbor in st to p
StdOut.println("nearest neighbor: " + st.nearest(p));
// generate an axis-aligned rectangle rect and find all points in st
// contained in rect
RectHV rect = new RectHV(0.0, 0.0, 0.5, 0.5);
StdOut.println("points in lower-left quadrant of unit square: "
+ st.range(rect));
// analysis of running time with input1M.txt: generate a random point in
// the unit square and make a call to nearest, for m num of times;
// measure the time this takes
// int m = 100;
// Stopwatch timer = new Stopwatch();
// for (int i = 0; i < m; i++) {
// Point2D rand = new Point2D(StdRandom.uniform(0.0, 1.0),
// StdRandom.uniform(0.0, 1.0));
// st.nearest(rand);
// }
// StdOut.println(timer.elapsedTime());
}
}