Skip to content

Commit 41ab384

Browse files
committed
Added 22_07 Exercise Solution. Cleaned up.
1 parent 6b7ba21 commit 41ab384

File tree

8 files changed

+330
-6
lines changed

8 files changed

+330
-6
lines changed

ch_03/Exercise03_09.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package ch_03;
22

3-
import javafx.scene.transform.Scale;
4-
5-
import java.io.BufferedReader;
6-
import java.io.IOException;
7-
import java.io.InputStreamReader;
83
import java.util.Scanner;
94

105
/**

ch_22/exercise22_07/CompareY.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package ch_22.exercise22_07;
2+
3+
import java.util.Comparator;
4+
5+
public class CompareY implements Comparator<Point> {
6+
@Override
7+
public int compare(Point p1, Point p2) {
8+
int resultY;
9+
if (p1.y < p2.y) {
10+
resultY = -1;
11+
} else if (p1.y > p2.y) {
12+
resultY = 1;
13+
} else {
14+
resultY = 0;
15+
}
16+
if (resultY == 0) {
17+
if (p1.x < p2.x) {
18+
return -1;
19+
}
20+
if (p1.x > p2.x) {
21+
return 1;
22+
}
23+
return 0;
24+
}
25+
return resultY;
26+
}
27+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package ch_22.exercise22_07;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
import java.util.Random;
7+
8+
/**
9+
* *22.7 (Closest pair of points) Section 22.8 introduced an algorithm for finding the
10+
* closest pair of points using a divide-and-conquer approach.
11+
* <p>
12+
* Implement the algorithm to meet the following requirements:
13+
* ■ Define the classes Point and CompareY in the same way as in Programming Exercise 20.4.
14+
* ■ Define a class named Pair with the data fields p1 and p2 to represent two
15+
* points, and a method named getDistance() that returns the distance
16+
* between the two points.
17+
* </p>
18+
* ---------------------------------------------------------------------- <br>
19+
* ■ Implement the following methods:
20+
* /** Return the distance of the closest pair of points *
21+
* public static Pair getClosestPair(double[][] points)
22+
* ---------------------------------------------------------------------- <br>
23+
* /** Return the distance of the closest pair of points
24+
* public static Pair getClosestPair(Point[] points)
25+
* ---------------------------------------------------------------------- <br>
26+
* /** Return the distance of the closest pair of points
27+
* in pointsOrderedOnX[low..high]. This is a recursive
28+
* method. pointsOrderedOnX and pointsOrderedOnY are
29+
* not changed in the subsequent recursive calls. *
30+
* public static Pair distance(Point[] pointsOrderedOnX, int low, int high, Point[] pointsOrderedOnY)
31+
* *************************************************************************************************
32+
* <p>
33+
* From Section 22.8:
34+
* LISTING 22.8 Algorithm for Finding the Closest Pair
35+
* Step 1: Sort the points in increasing order of x-coordinates. For the
36+
* points with the same x-coordinates, sort on y-coordinates. This results
37+
* in a sorted list S of points.
38+
* Step 2: Divide S into two subsets, S1 and S2, of equal size using the
39+
* midpoint in the sorted list. Let the midpoint be in S1. Recursively find
40+
* the closest pair in S1 and S2. Let d1 and d2 denote the distance of the
41+
* closest pairs in the two subsets, respectively.
42+
* Step 3: Find the closest pair between a point in S1 and a point in S2 and
43+
* denote their distance as d3
44+
* </p>
45+
*/
46+
public class Exercise22_07 {
47+
private static Point[] S = new Point[]{new Point(65.72438591548975, 167.6922117473909),
48+
new Point(182.85174298311438, 575.9888358534622),
49+
new Point(240.22902231427315, 175.37793004083213),
50+
new Point(317.5674265676426, 278.78240371327325),
51+
new Point(356.00061370323124, 337.3921411106672),
52+
new Point(302.54686547351093, 59.079345054498475),
53+
new Point(163.48579149126033, 749.1901740238649),
54+
new Point(277.76518877799515, 420.1256294206885),
55+
new Point(108.51033510595356, 21.982331832110937),
56+
new Point(108.5270214151543, 160.55324389043895),
57+
};
58+
59+
public static void main(String[] args) {
60+
Pair closestPair = getClosestPair(S);
61+
System.out.println("Closest Pair is: ");
62+
System.out.println(closestPair.toString());
63+
64+
}
65+
66+
/**
67+
* Return the distance of the closest pair of points
68+
*/
69+
public static Pair getClosestPair(double[][] points) {
70+
/* Convert to Point[] */
71+
Point[] pts = new Point[points.length];
72+
int idx = 0;
73+
for (double[] pt : points) {
74+
pts[idx] = new Point(pt[0], pt[1]);
75+
idx++;
76+
}
77+
/* Use Point[] method to share common logic */
78+
return getClosestPair(pts);
79+
}
80+
81+
/**
82+
* Return the distance of the closest pair of points
83+
*/
84+
public static Pair getClosestPair(Point[] pointsOrderedOnX) {
85+
/* Sort Points by X first order, see Point.java */
86+
Arrays.sort(pointsOrderedOnX);
87+
/* Create deep copy of pointsOrderedOnX array */
88+
Point[] pointsOrderedOnY = pointsOrderedOnX.clone();
89+
/* Sort pointsOrderedOnY by Y first order, see CompareY.java*/
90+
Arrays.sort(pointsOrderedOnY, new CompareY());
91+
/* Start recursion at low = startIndex, and high = endIndex */
92+
return distance(pointsOrderedOnX, 0, pointsOrderedOnX.length - 1, pointsOrderedOnY);
93+
94+
}
95+
96+
/**
97+
* Return the distance of the closest pair of points
98+
* in pointsOrderedOnX[low..high]. This is a recursive
99+
* method. pointsOrderedOnX and pointsOrderedOnY are
100+
* not changed in the subsequent recursive calls.
101+
*/
102+
public static Pair distance(Point[] pointsOrderedOnX,
103+
int low, int high, Point[] pointsOrderedOnY) {
104+
if (low >= high) {/* Recursive stopping condition */
105+
return null;
106+
} else if (low + 1 == high) { /* Only 2 Points possible to pair: pointsOrderedOnX[low], pointsOrderedOnX[high] */
107+
return new Pair(pointsOrderedOnX[low], pointsOrderedOnX[high]);
108+
} else {
109+
/* Divide and Conquer */
110+
int mid = (low + high) / 2;
111+
/* Split sorted in half into S1 and S2, let d1 and d2 denote the distance of the closest pair in each subset */
112+
Pair S1 = distance(pointsOrderedOnX, low, mid, pointsOrderedOnY); //d1
113+
Pair S2 = distance(pointsOrderedOnX, mid + 1, high, pointsOrderedOnY); // d2
114+
/* Find minDistance = min(d1,d2) distance */
115+
double d = 0;
116+
Pair p = null;
117+
if (S1 != null && S2 != null) {
118+
double leftPairDistance = S1.getDistance();
119+
double rightPairDistance = S1.getDistance();
120+
d = Math.min(leftPairDistance, rightPairDistance);
121+
p = leftPairDistance == d ? S1 : S2;
122+
} else if (S1 != null) {
123+
d = S1.getDistance();
124+
p = S1;
125+
} else if (S2 != null) {
126+
d = S2.getDistance();
127+
p = S2;
128+
}
129+
130+
List<Point> stripL = new ArrayList<>();
131+
List<Point> stripR = new ArrayList<>();
132+
/* Obtain stripL and stripR */
133+
for (Point point : pointsOrderedOnY) {
134+
/* if (p is in S1 and mid.x – p.x <= d) */
135+
if (point.getX() <= pointsOrderedOnX[mid].getX() && pointsOrderedOnX[mid].getX() - point.getX() <= d) {
136+
stripL.add(point);
137+
/* else if (p is in S2 and p.x - mid.x <= d) */
138+
} else if (point.getX() > pointsOrderedOnX[mid].getX() && point.getX() - pointsOrderedOnX[mid].getX() <= d) {
139+
stripR.add(point);
140+
}
141+
}
142+
143+
int r = 0; // The index of the point in stripE
144+
for (Point point : stripL) {
145+
// Skip the points in stripR below p.y - d
146+
while (r < stripR.size() && stripR.get(r).getY() <= point.getY() - d) {
147+
r++;
148+
}
149+
int r1 = r;
150+
while (r1 < stripR.size() && Math.abs(stripR.get(r1).getY() - point.getY()) <= d) {
151+
/* Check if (p, q[r1]) is a possible closest pair */
152+
if (new Pair(point, stripR.get(r1)).getDistance() < d) {
153+
d = new Pair(point, stripR.get(r1)).getDistance();
154+
p.setP1(point);
155+
p.setP2(stripR.get(r1));
156+
}
157+
r1++;
158+
}
159+
}
160+
return p;
161+
}
162+
}
163+
}

ch_22/exercise22_07/Pair.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package ch_22.exercise22_07;
2+
3+
/**
4+
* ■ Define a class named Pair with the data fields p1 and p2 to represent two
5+
* points, and a method named getDistance() that returns the distance
6+
* between the two points.
7+
*/
8+
public class Pair {
9+
private Point p1;
10+
private Point p2;
11+
12+
public Pair(){}
13+
14+
public Pair(Point p1, Point p2) {
15+
this.p1 = p1;
16+
this.p2 = p2;
17+
}
18+
19+
double getDistance() {
20+
if (p1 == null || p2 == null) throw new IllegalArgumentException("Pair must have 2 non-null points defined....");
21+
return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2));
22+
}
23+
24+
public Point getP1() {
25+
return p1;
26+
}
27+
28+
public void setP1(Point p1) {
29+
this.p1 = p1;
30+
}
31+
32+
public Point getP2() {
33+
return p2;
34+
}
35+
36+
public void setP2(Point p2) {
37+
this.p2 = p2;
38+
}
39+
40+
41+
@Override
42+
public String toString() {
43+
return "Pair{" +
44+
"p1=" + p1 +
45+
", p2=" + p2 +
46+
'}';
47+
}
48+
}

ch_22/exercise22_07/Point.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package ch_22.exercise22_07;
2+
3+
/**
4+
* ■ Define a class named Point with two data fields x and y to represent a
5+
* * point’s x- and y-coordinates.
6+
* Implement the Comparable interface for comparing the points on x-coordinates.
7+
* If two points have the same x-coordinates, compare their y-coordinates.
8+
*/
9+
public class Point implements Comparable<Point> {
10+
double x;
11+
double y;
12+
13+
public Point(double x, double y) {
14+
this.x = x;
15+
this.y = y;
16+
}
17+
18+
public double getX() {
19+
return x;
20+
}
21+
22+
public Point setX(double x) {
23+
this.x = x;
24+
return this;
25+
}
26+
27+
public double getY() {
28+
return y;
29+
}
30+
31+
public Point setY(double y) {
32+
this.y = y;
33+
return this;
34+
}
35+
36+
37+
@Override
38+
public String toString() {
39+
return "Point{" +
40+
"x=" + x +
41+
", y=" + y +
42+
"}\n";
43+
}
44+
45+
@Override
46+
public int compareTo(Point that) {
47+
if (this.x == that.x) {
48+
if (this.y < that.y) {
49+
return -1;
50+
}
51+
if (this.y > that.y) {
52+
return 1;
53+
}
54+
return 0; // this.y == that.y
55+
56+
} else {
57+
if (this.x < that.x) {
58+
return -1;
59+
}
60+
if (this.x > that.x) {
61+
return 1;
62+
}
63+
return 0;//this.x == that.x
64+
65+
}
66+
}
67+
}

ch_22/package-info.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* <p>
3+
* Chapter Twenty-Two:
4+
* -------- Developing Efficient Algorithms --------
5+
* Solutions for
6+
* "Introduction to Java Programming" by Daniel Liang 10th Edition
7+
* </p>
8+
*
9+
* @author Harry Dulaney
10+
*/
11+
package ch_22;

ch_23/package-info.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* <p>
3+
* Chapter Twenty-Three:
4+
* -------- Sorting --------
5+
* Solutions for
6+
* "Introduction to Java Programming" by Daniel Liang 10th Edition
7+
* </p>
8+
*
9+
* @author Harry Dulaney
10+
*/
11+
package ch_23;

ch_25/package-info.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/**
22
* <p>
3-
* Chapter Twenty-Five Solutions for
3+
* Chapter Twenty-Five
4+
* ------------ Binary Search Trees -------------
5+
* Solutions for
46
* "Introduction to Java Programming" by Daniel Liang 10th Edition
57
* </p>
68
*

0 commit comments

Comments
 (0)