File I/O, serialization, 알고리즘 문제(백준)

yeolyeol·2024년 7월 29일
0

ssafy12

목록 보기
18/32
post-thumbnail

금요일이다. 햄보카다.


File

✨내용에 관여하지 않음

메서드 명선언부와 설명
File()public File(String pathname) : pathname에 해당하는 파일을 생성한다. 경로 없이 파일을 생성하면 애플리케이션을 시작한 경로가 됨.
public File(File parent, String child) : parent 경로 아래 child를 생성
public File(URI uri) : file로 시작하는 URI 객체를 이용해 파일을 생성한다.
createNewFile()public boolean createNewFile() throws IOException : 새로운 물리적인 파일을 생성.
mkdir()public boolean mkdir() : 새로운 디렉토리 생성
mkdirs()public boolean mkdirs() : 경로상에 없는 모든 디렉토리를 생성
delete()public boolean delete() : 파일 또는 디렉토리 삭제

Serialization

객체 직렬화

객체를 파일 등에 저장하거나 네트워크로 전송하기 위해 연속적인 데이터로 변환하는 것

말이 어렵지만 쉽게 말해 데이터화 시키는 것이다.
즉, 하나의 JVM에서는 메모리 주소를 참조하며 공유하는데,
두 개 이상의 JVM에서는 서로 메모리 주소도 다르며 메모리에 다른 값이 이미 있을 가능성이 높다.
그래서 메모리 주소가 아닌 실제 값을 데이터화 하여 전송해야 같은 값을 공유할 수 있다.

조건

  • Serializable 인터페이스를 구현
  • 클래스의 모든 멤버가 Serializable 인터페이스를 구현해야 함
    ⚠ 직렬화에서 제외하려는 멤버는 transient 선언하면 됨.
class Person implements Serializable /* 직렬화 필수 조건 */{
	private String name;
    private int age;
    
    private transient String ssn; // transient 선언으로 직렬화에서 제외
    private LoginInfo lInfo; // 객체 타입이라 직렬화 필요
}

serialVersionUID

클래스의 변경 여부를 파악하기 위한 유일키
약간 DB의 PK와 비슷하다고 생각하면 편하다.

직렬화를 구현한 객체의 버전이 달라질 수 있다.(직렬화 할 요소가 늘었다던지, 줄었다던지 등등)
이때 같은 UID인 객체를 불러오면 런타임 예외가 나게된다.

직렬화 할 때의 UID와 역직렬화 할 때의 UID가 다르면 예외 발생

그래서 변경할 때마다 새로운 UID를 만들어 버전을 관리하기 할 수 있다.


알고리즘 문제 풀기

BOJ 13418 학교 탐방하기

public class Main {
	static class Road{
		int from;
		int to;
		int ramp;
		
		public Road(int from, int to, int ramp) {
			super();
			this.from = from;
			this.to = to;
			this.ramp = ramp;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		
		long min = 0;
		long max = 0;
		
		int[] parents = new int[n + 1];
		for(int i = 0; i < n + 1; i++) {
			parents[i] = i;
		}
		
		List<Road> list = new ArrayList<>();
		for(int i = 0; i < m + 1; i++) {
			st = new StringTokenizer(br.readLine());
			int from = Integer.parseInt(st.nextToken());
			int to = Integer.parseInt(st.nextToken());
			int ramp = Integer.parseInt(st.nextToken());
			list.add(new Road(from, to, ramp));
		}
		
		// 1. 가장 많은 피로도
		Collections.sort(list, new Comparator<Road>() {
			@Override
			public int compare(Road o1, Road o2) {
				if(o1.ramp == o2.ramp) {
					return o1.from - o2.from;
				}
				return o1.ramp - o2.ramp;
			}
		});
		
		for(Road road : list) {
			if(!isSameParent(parents, road.from, road.to)) {
				union(parents, road.from, road.to);
				if(road.ramp == 0) min++;
			}
		}
		
		// 2. 가장 적은 피로도
		for(int i = 0; i < n + 1; i++) {
			parents[i] = i;
		}
		
		Collections.sort(list, new Comparator<Road>() {
			@Override
			public int compare(Road o1, Road o2) {
				if(o2.ramp == o1.ramp) {
					return o2.ramp - o1.ramp;
				}
				return o2.ramp - o1.ramp;
			}
		});
		
		for(Road road : list) {
			if(!isSameParent(parents, road.from, road.to)) {
				union(parents, road.from, road.to);
				if(road.ramp == 0) max++;
			}
		}
		
		long ans = min * min - max * max;
		System.out.println(ans);
	}
	
	static boolean isSameParent(int[] parents, int from, int to) {
		from = findParent(parents, from);
		to = findParent(parents, to);
		
		return from == to;
	}
	
	static int findParent(int[] parents, int from) {
		if(from != parents[from]) {
			return parents[from] = findParent(parents, parents[from]);
		}
		return parents[from];
	}
	
	static void union(int[] parents, int from, int to) {
		from = findParent(parents, from);
		to = findParent(parents, to);
		
		parents[to] = from;
	}
}

풀이 요약
전형적인 MST 알고리즘인 것 같다.
라고 말하기엔 수많은 틀렸습니다를 봤는데, 크루스칼 알고리즘엔 문제가 없어서 사소한 코드 하나하나 고칠 때마다 제출을 했다.
결과적으로 변수 하나를 잘 못 적어서 난 이슈였다..

문제 풀이시 주의 사항
1. 0(입구)부터 시작한다.
2. 오르막이 0, 내리막이 1

profile
한 걸음씩 꾸준히

0개의 댓글

Powered by GraphCDN, the GraphQL CDN