Algorithm/프로그래머스

프로그래머스 - 표 편집

whyWhale 2023. 4. 12.

문제 설명

주어진 명령을 따라 이행한 뒤 그에 맞는 표 값을 출력하는 문제이다.

완벽한 구현문제이다.

자료구조를 어떻게 사용하지도 물어보는 문제인것같다.

 

TRY 

2차원 배열과 map 이 두가지를 이용했다.

2차원 배열에는 각 칸이 가지고 있는 문자값을 저장했고

map에는 해당 칸과 연관되어 있는 각 칸들의 정보를 저장했다.

왜냐하면 병합 또는 병합제거, 정보 수정에 이전에 수행했던 연관되어 있는 칸들이 필요했기 때문이다.

  • 병합시 - 이전에 수행된 연관정보들로 부터 추가로 병합을 이어나가야 하기 때문.
  • 병합제거 - 이전에 수행된 연관정보들 모두 초기화 해야하기 때문.
  • 정보수정 - r,c와 병합을 한 셀들을 기반으로 모든 값을 교체해야하기 때문.

주의사항

다른 연관관계를 이어붙이기 위한 과정에서 변경에 대한 파급력있을 수 있어 답이 달라지거나 중간 처리과정이 예상치 못한 오작동으로 이어질 수 있음에 유의해야한다.

자바에서 제공하는 Collection들은 addAll()은 깊은 복사가 아님을 유의해야 한다.

이부분은 API로 제공하지 않아 직접 코드로 작성해줘야한다.

지속적으로 객체를 새로 생성해야 한다.

풀이


/**
    merget r1 c1 r2 c2의
     - 두개의 칸 중 셀값을 갖고 있으면 그 값을 가짐
     - 두개 모두 값을 가지고 있으면 (r1,c1) 의 값을 가짐. - 앞의 출열한 칸의 값으로 통일
     - r1.c1  와 r2 c2 중 어느 위치를 선택하여도 병합된 셀로 접근함.
     - 입출력1 : merge (1,2)-"menu" , (1,3)-"null" -> [(1,2),(1,3)] - "menu" 
               merge (1,3) - "menu", (1,4)-"null" -> [(1,2),(1,3),(1,4)] - "menu"
               unmerge (1,4) - (1,2)-"null", (1,3)-"null", (1,4)-"menu" := 병합 모두 해제됨과 통시 unmerge에 출연한 값만
    - core:자료구조 및 모델링를 잘 사용해야 하는 문제인듯
    */
    class Node {
		int y, x;

		public Node(int y, int x) {
			this.y = y;
			this.x = x;
		}

		public boolean equals(Object o) {
			if (this == o)
				return true;

			if (o == null || this.getClass() != o.getClass()) {
				return false;
			}

			Node other = (Node)o;

			return this.y == other.y && this.x == other.x;
		}

		public int hashCode() {
			return Objects.hash(this.y, this.x);
		}
	}

	public String[] solution(String[] commands) {
		List<String> answer = new ArrayList<>();
		String[][] map = new String[51][51]; // 값 저장
		Map<Node, List<Node>> status = new LinkedHashMap<>(); //병합 정보
		for (int i = 0; i < map.length; i++) {
			Arrays.fill(map[i], "");
			for (int j = 0; j < map[0].length; j++) {
				status.put(new Node(i, j), new ArrayList<>());
			}

		}

		for (String cmd : commands) {
			String str[] = cmd.split(" ");

			switch (str[0]) {
				case "UPDATE":
					if (str.length == 4) {
						// UPDATE ${r} ${c} ${value}
						int r = Integer.parseInt(str[1]);
						int c = Integer.parseInt(str[2]);
						map[r][c] = str[3];
						for (Node node : status.get(new Node(r, c))) {
							map[node.y][node.x] = map[r][c];
						}

					} else {
						// UPDATE ${before} ${after}
						String before = str[1];
						String after = str[2];
						for (int i = 0; i < map.length; i++) {
							for (int j = 0; j < map[0].length; j++) {
								if (map[i][j].equals(before)) {
									map[i][j] = after;
								}
							}
						}
					}
					break;
				case "MERGE":
					int r1 = Integer.parseInt(str[1]);
					int c1 = Integer.parseInt(str[2]);
					int r2 = Integer.parseInt(str[3]);
					int c2 = Integer.parseInt(str[4]);

					String val1 = map[r1][c1];
					String val2 = map[r2][c2];
					String val = "";
					if (!val1.isEmpty() && !val2.isEmpty()) {
						val = map[r2][c2] = map[r1][c1];
					} else if (val1.isEmpty() && !val2.isEmpty()) {
						val = map[r1][c1] = map[r2][c2];
					} else if (!val1.isEmpty() && val2.isEmpty()) {
						val = map[r2][c2] = map[r1][c1];
					} else {
						System.out.println("둘다 읎네?");
					}

					Set<Node> relations = new HashSet<>();

					List<Node> nodes1 = status.get(new Node(r1, c1));
					for (Node prev : nodes1) {
						relations.add(new Node(prev.y, prev.x));
					}

					List<Node> nodes = status.get(new Node(r2, c2));
					for (Node prev : nodes) {
						relations.add(new Node(prev.y, prev.x));
					}

					relations.add(new Node(r1, c1));
					relations.add(new Node(r2, c2));

					for (Node node : relations) {
						status.put(node, relations.stream().collect(Collectors.toList()));
						map[node.y][node.x] = val;
					}

					break;
				case "UNMERGE":
					int r = Integer.parseInt(str[1]);
					int c = Integer.parseInt(str[2]);

					String value = map[r][c];
					for (Node node : status.get(new Node(r, c))) {
						status.put(node, new ArrayList<>());
						map[node.y][node.x] = "";
					}

					map[r][c] = value;

					break;
				case "PRINT":
					int y = Integer.parseInt(str[1]);
					int x = Integer.parseInt(str[2]);
					if (map[y][x].isEmpty()) {
						answer.add("EMPTY");
					} else {
						answer.add(map[y][x]);
					}
					break;
			}
		}
		return answer.toArray(String[]::new);

	}

댓글