Skip to content

Commit f13526e

Browse files
committed
add Closest Pair of Points & Loop Invariant Algorithm
1 parent 0057bed commit f13526e

File tree

2 files changed

+272
-0
lines changed

2 files changed

+272
-0
lines changed

03/ClosestPair.java

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
package hw03;
2+
3+
import java.io.BufferedReader;
4+
import java.io.FileNotFoundException;
5+
import java.io.FileReader;
6+
import java.io.IOException;
7+
import java.util.StringTokenizer;
8+
9+
public class ClosestPair {
10+
private Coordinates[] arr;
11+
12+
ClosestPair(String filePath){
13+
String data = this.readFile(filePath);
14+
StringTokenizer str = new StringTokenizer(data, " |\n");
15+
arr = new Coordinates[str.countTokens()/2];
16+
for(int i = 0; str.hasMoreTokens(); i++){
17+
arr[i] = new Coordinates(Double.parseDouble(str.nextToken()), Double.parseDouble(str.nextToken()));
18+
}
19+
}
20+
21+
public double doClosetPair(){
22+
quickSortX(this.arr, 0, this.arr.length-1);
23+
return closestPair(this.arr, 0, this.arr.length-1);
24+
}
25+
26+
private double closestPair(Coordinates[] arr, int start, int end){
27+
28+
// Brute Force
29+
if(end - start + 1 == 3){ // 점 3개 최소값 비교
30+
double distance1 = calculateDistance(arr[start], arr[start+1]);
31+
double distance2 = calculateDistance(arr[start+1], arr[start+2]);
32+
double distance3 = calculateDistance(arr[start], arr[start+2]);
33+
34+
double minDistance1 = mininumDistance(distance1, distance2);
35+
double minDistance = mininumDistance(minDistance1, distance3);
36+
37+
return minDistance;
38+
}
39+
else if(end - start + 1 == 2){ // 점 2개 최소값 비교
40+
double minDistance = calculateDistance(arr[start], arr[start+1]);
41+
return minDistance;
42+
}
43+
else{ // 점 3개 초과
44+
int halfIndex = (start + end)/ 2;
45+
double halfX = (arr[halfIndex].x + arr[halfIndex+1].x) / 2;
46+
double distance1 = closestPair(arr, start, halfIndex);
47+
double distance2 = closestPair(arr, halfIndex+1, end);
48+
double distance = mininumDistance(distance1, distance2);
49+
Coordinates[] arr2;
50+
double temp = distance;
51+
double tempDistance = 0;
52+
53+
int leftIndex = calcLeftIndex(arr, halfIndex, halfX, distance);
54+
int rightIndex = calcRightIndex(arr, halfIndex + 1, halfX, distance);
55+
if(rightIndex != -1 || leftIndex != -1) { // 더 작은 길이가 존재할때
56+
if(leftIndex == -1) { // 왼쪽면이 d보다 작을때
57+
arr2 = new Coordinates[rightIndex - (halfIndex + 1) + 1];
58+
System.arraycopy(arr, halfIndex + 1, arr2, 0, arr2.length);
59+
quickSortY(arr2, 0, arr2.length - 1);
60+
}else if(rightIndex == -1){ // 오른쪽면이 d보다 작을때
61+
arr2 = new Coordinates[halfIndex - leftIndex + 1];
62+
System.arraycopy(arr, leftIndex, arr2, 0, arr2.length);
63+
quickSortY(arr2, 0, arr2.length - 1);
64+
}else{ //양쪽면에 원소가 있을 때
65+
arr2 = new Coordinates[rightIndex - leftIndex + 1];
66+
System.arraycopy(arr, leftIndex, arr2, 0, arr2.length);
67+
quickSortY(arr2, 0, arr2.length - 1);
68+
}
69+
}else{ // 작은 길이 없을때
70+
return distance;
71+
}
72+
73+
// y축 거리 최소값 비교
74+
for(int i = 0; i < arr2.length - 1 ; i++){
75+
tempDistance = calculateDistance(arr2[i], arr2[i+1]);
76+
if(tempDistance < temp){
77+
temp = tempDistance;
78+
}
79+
}
80+
return temp;
81+
}
82+
}
83+
84+
85+
private int calcLeftIndex(Coordinates[] arr, int halfIndex, double halfX, double distance){
86+
int leftIndex;
87+
if(Math.abs(arr[halfIndex].x - halfX) >= distance) return -1;
88+
for(leftIndex = halfIndex; leftIndex > 0; leftIndex--){
89+
if(Math.abs(arr[leftIndex].x - halfX) < distance) continue;
90+
else break;
91+
}
92+
return leftIndex;
93+
}
94+
95+
96+
private int calcRightIndex(Coordinates[] arr, int halfIndex, double halfX, double distance){
97+
int rightIndex;
98+
if(Math.abs(arr[halfIndex].x - halfX) >= distance) return -1;
99+
for(rightIndex = halfIndex; rightIndex < arr.length - 1; rightIndex++){
100+
if(Math.abs(arr[rightIndex].x - halfX) < distance) continue;
101+
else break;
102+
}
103+
return rightIndex;
104+
}
105+
106+
private double mininumDistance(double distance1, double distance2){
107+
if(distance1 > distance2) return distance2;
108+
return distance1;
109+
}
110+
111+
private void quickSortY(Coordinates[] arr, int p, int r){
112+
if(p < r){
113+
int pivotIndex = partitionY(arr, p, r);
114+
quickSortY(arr, p, pivotIndex-1);
115+
quickSortY(arr, pivotIndex+1, r);
116+
}
117+
};
118+
119+
private int partitionY(Coordinates[] arr, int p, int r){
120+
double target = arr[r].y;
121+
int i = p-1;
122+
int j = p;
123+
while(j <= r-1){ // j가 끝 인덱스 전까지 탐색하도록
124+
if(arr[j].y <= target){
125+
i++;
126+
swap(arr, i, j);
127+
}
128+
j++;
129+
}
130+
i++;
131+
swap(arr, i, j);
132+
return i;
133+
}
134+
135+
private void quickSortX(Coordinates[] arr, int p, int r){
136+
if(p < r){
137+
int pivotIndex = partitionX(arr, p, r);
138+
quickSortX(arr, p, pivotIndex-1);
139+
quickSortX(arr, pivotIndex+1, r);
140+
}
141+
}
142+
143+
private int partitionX(Coordinates[] arr, int p, int r){
144+
double target = arr[r].x;
145+
int i = p-1;
146+
int j = p;
147+
while(j <= r-1){ // j가 끝 인덱스 전까지 탐색하도록
148+
if(arr[j].x <= target){
149+
i++;
150+
swap(arr, i, j);
151+
}
152+
j++;
153+
}
154+
i++;
155+
swap(arr, i, j);
156+
return i;
157+
}
158+
159+
private void swap(Coordinates[] arr, int i, int j){
160+
Coordinates temp = arr[i];
161+
arr[i] = arr[j];
162+
arr[j] = temp;
163+
}
164+
165+
166+
private double calculateDistance(Coordinates a, Coordinates b){
167+
return Math.abs(Math.sqrt(Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y,2)));
168+
}
169+
170+
private String readFile(String filePath) {
171+
BufferedReader br = null;
172+
StringTokenizer str = null;
173+
StringBuilder sb = null;
174+
String line;
175+
176+
try {
177+
br = new BufferedReader(new FileReader(filePath));
178+
sb = new StringBuilder();
179+
while ((line = br.readLine()) != null) {
180+
sb.append(line+"\n");
181+
}
182+
} catch (FileNotFoundException e) {
183+
e.printStackTrace();
184+
} catch (IOException e) {
185+
e.printStackTrace();
186+
} finally {
187+
if (br != null) {
188+
try {
189+
br.close();
190+
} catch (IOException e) {
191+
e.printStackTrace();
192+
}
193+
}
194+
return sb.toString();
195+
}
196+
}
197+
198+
private class Coordinates{
199+
double x, y;
200+
public Coordinates(double x, double y){
201+
this.x = x;
202+
this.y = y;
203+
}
204+
}
205+
}

03/LoopInvariant.java

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package hw03;
2+
3+
import java.io.BufferedReader;
4+
import java.io.FileNotFoundException;
5+
import java.io.FileReader;
6+
import java.io.IOException;
7+
import java.util.StringTokenizer;
8+
9+
public class LoopInvariant {
10+
int arr[];
11+
12+
LoopInvariant(String filePath) {
13+
String data = this.readFile(filePath);
14+
StringTokenizer str = new StringTokenizer(data, " ");
15+
arr = new int[str.countTokens()];
16+
for (int i = 0; str.hasMoreTokens(); i++) {
17+
arr[i] = Integer.parseInt(str.nextToken());
18+
}
19+
}
20+
21+
22+
public int binarySearch(int value) {
23+
int start = 0;
24+
int end = this.arr.length - 1;
25+
while (end != start) {
26+
int mid = (start + end) / 2;
27+
if (this.arr[mid] >= value) {
28+
end = mid;
29+
} else {
30+
start = mid + 1;
31+
}
32+
}
33+
if (this.arr[start] == value) return start;
34+
return -1;
35+
}
36+
37+
38+
39+
private String readFile(String filePath) {
40+
BufferedReader br = null;
41+
StringTokenizer str = null;
42+
StringBuilder sb = null;
43+
String line;
44+
45+
try {
46+
br = new BufferedReader(new FileReader(filePath));
47+
sb = new StringBuilder();
48+
while ((line = br.readLine()) != null) {
49+
sb.append(line);
50+
}
51+
} catch (FileNotFoundException e) {
52+
e.printStackTrace();
53+
} catch (IOException e) {
54+
e.printStackTrace();
55+
} finally {
56+
if (br != null) {
57+
try {
58+
br.close();
59+
} catch (IOException e) {
60+
e.printStackTrace();
61+
}
62+
}
63+
return sb.toString();
64+
}
65+
}
66+
67+
}

0 commit comments

Comments
 (0)