import java.util.TreeSet;
public class BitmapToGraph
{
int[] dx = {-1,0,1,1,1,0,-1,-1};
int[] dy = {-1,-1,-1,0,1,1,1,0};
int n,m;
String[] bmap;
char check(int nx, int ny) {
return (nx<0 || nx>=m || ny<0 || ny>=n) ? '.' : bmap[ny].charAt(nx);
}
public String[] parse(String[] bitmap) {
bmap = bitmap;
n = bitmap.length;
m = bitmap[0].length();
int node = 0;
int[][] num = new int[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (bitmap[i].charAt(j) == 'N')
num[i][j] = node++;
boolean[][] e = new boolean[n][m];
String[] res = new String[node];
for (int i = 0; i < node; i++) res[i] = "";
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (bitmap[i].charAt(j) == 'N') {
TreeSet<Integer> set = new TreeSet<Integer>();
for (int d = 0; d < 8; d++) {
int nx = j + dx[d];
int ny = i + dy[d];
if (check(nx,ny)=='E' && e[ny][nx]) continue;
int d1 = d;
int cnt = 0;
while (check(nx,ny) == 'E') {
if (check(nx+dx[d1],ny+dy[d1]) == '.') {
if (check(nx+dx[(d1+7)%8],ny+dy[(d1+7)%8]) != '.')
d1 = (d1+7)%8;
else if (check(nx+dx[(d1+1)%8],ny+dy[(d1+1)%8]) != '.')
d1 = (d1+1)%8;
}
nx += dx[d1];
ny += dy[d1];
cnt++;
}
if (cnt != 0) {
if (num[i][j] == num[ny][nx]) e[ny-dy[d1]][nx-dx[d1]] = true;
set.add(num[ny][nx]*100000+cnt*10+d);
}
}
boolean comma = false;
for (int s : set) {
if(comma) res[num[i][j]] += ",";
res[num[i][j]] += s/100000 + ":" + (s%100000)/10;
comma = true;
}
}
}
}
return res;
}
}
Explanation
boolean[][] e는 단일 고리(self loop)의 마지막 변을 나타내기 위한 배열이다. 이를 통해 단일 고리는 정확히 한 번만 더해진다.
(d1+7)%8과 (d1+1)%8을 통해 45도 각도로 나아갈 수 있다. 자리수 계산을 위해 목적지 노드 숫자에 100000을 곱하고 길이에 10을 곱한다. d를 더해주는 것은 같은 길이를 가진 방향이 다른 변들을 허용하기 위함이다.
References
최근 덧글