나를 기록하다
article thumbnail
반응형

9월 30일은 세미나를 보고 정리한 내용만 올리고 오랜만에 한국으로 돌아온 친구, 타지에서 일하는 친구들이 모두 부산에 모여서 친구들을 만났고, 10월 1일은 부모님과 함께 보냈다. 번아웃으로 조금 힘든 날들을 보내고 있었는데 오랜만에 공부를 잠깐 쉬어가면서 사람들을 만나니 다시 에너지를 얻은 기분이다. 역시 공부와 휴식이 조화를 이룰 때 공부도, 휴식도 잘할 수 있는 게 맞다.

 

오늘은 본가에 다녀와서 짧게나마 알고리즘 문제풀이와 객체지향의 사실과 오해를 읽고 정리했다.

TIL-37 시작하겠다.

 

백준 4949 자바(Java) 균형잡힌 세상

https://www.acmicpc.net/problem/4949

 

4949번: 균형잡힌 세상

각 문자열은 마지막 글자를 제외하고 영문 알파벳, 공백, 소괄호("( )"), 대괄호("[ ]")로 이루어져 있으며, 온점(".")으로 끝나고, 길이는 100글자보다 작거나 같다. 입력의 종료조건으로 맨 마지막에

www.acmicpc.net


시간 메모리 제한 제출 정답 맞힌 사람 정답 비율
1 초 128 MB 112292 37675 29347 32.489%

문제

세계는 균형이 잘 잡혀있어야 한다. 양과 음, 빛과 어둠 그리고 왼쪽 괄호와 오른쪽 괄호처럼 말이다.

정민이의 임무는 어떤 문자열이 주어졌을 때, 괄호들의 균형이 잘 맞춰져 있는지 판단하는 프로그램을 짜는 것이다.

문자열에 포함되는 괄호는 소괄호("()") 와 대괄호("[]")로 2종류이고, 문자열이 균형을 이루는 조건은 아래와 같다.

  • 모든 왼쪽 소괄호("(")는 오른쪽 소괄호(")")와만 짝을 이뤄야 한다.
  • 모든 왼쪽 대괄호("[")는 오른쪽 대괄호("]")와만 짝을 이뤄야 한다.
  • 모든 오른쪽 괄호들은 자신과 짝을 이룰 수 있는 왼쪽 괄호가 존재한다.
  • 모든 괄호들의 짝은 1:1 매칭만 가능하다. 즉, 괄호 하나가 둘 이상의 괄호와 짝지어지지 않는다.
  • 짝을 이루는 두 괄호가 있을 때, 그 사이에 있는 문자열도 균형이 잡혀야 한다.

정민이를 도와 문자열이 주어졌을 때 균형잡힌 문자열인지 아닌지를 판단해보자.

입력

 

각 문자열은 마지막 글자를 제외하고 영문 알파벳, 공백, 소괄호("( )"), 대괄호("[ ]")로 이루어져 있으며, 온점(".")으로 끝나고, 길이는 100글자보다 작거나 같다.

입력의 종료조건으로 맨 마지막에 온점 하나(".")가 들어온다.

출력

각 줄마다 해당 문자열이 균형을 이루고 있으면 "yes"를, 아니면 "no"를 출력한다.

 

나의 풀이

문제 분석
  1. 입력받은 문장을 순회하며 로직을 처리할 문자열 타입을 반환하는 judge 메서드 생성
  2. 괄호를 열고 닫는 문제는 LIFO이므로, 스택 자료구조를 사용
  3. 열린 괄호일 경우 스택에 추가
  4. 닫힌 괄호이고 스택이 비어있거나 짝이 맞지 않으면 no를 반환
  5. 괄호가 짝을 이루면 스택에서 제거
  6. 위의 과정을 거친 후 모든 괄호가 짝을 이루고 있고 스택이 비어있으면 yes를 반환
  7. 스택에 괄호가 남아있으면 no를 반환
  8. 효율을 위해 StringBuilder를 사용하였고, 입력이 "."일 때는 종료, 아닐 때는 입력받은 문장을 StringBuilder에 append함.
  9. while문이 break된 경우 StringBuilder에 저장된 내용을 출력
정답 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();

		while (true) {
			String sentence = br.readLine();
			if (sentence.equals(".")) {    // 입력이 '.'일 때 종료
				break;
			}
			sb.append(judge(sentence)).append('\n'); // judge 메서드 호출 후 결과를 StringBuilder에 추가
		}
		System.out.println(sb); // 결과 출력
	}

	public static String judge(String sentence) {
		Stack<Character> stack = new Stack<>(); // 문자를 저장할 스택 선언

		for (int i = 0; i < sentence.length(); i++) {
			char c = sentence.charAt(i);
			if (c == '(' || c == '[') { // 열린 괄호일 경우 스택에 추가
				stack.push(c);
			}
			if (c == ')' && (stack.empty() || stack.peek() != '(')) {
				// 닫힌 괄호이고, 스택이 비어있거나 짝이 맞지 않으면 "no" 반환
				return "no";
			}
			if (c == ')' && stack.peek() == '(') {
				stack.pop(); // 괄호가 짝을 이루면 스택에서 제거
			}
			if (c == ']' && (stack.empty() || stack.peek() != '[')) {
				// 닫힌 대괄호이고, 스택이 비어있거나 짝이 맞지 않으면 "no" 반환
				return "no";
			}
			if (c == ']' && stack.peek() == '[') {
				stack.pop(); // 대괄호가 짝을 이루면 스택에서 제거
			}
		}

		if (stack.empty()) {
			// 모든 괄호가 짝을 이루고 스택이 비어있으면 "yes" 반환
			return "yes";
		}
		return "no"; // 스택에 괄호가 남아있으면 "no" 반환
	}
}

객체지향적인 코드를 작성하기 위해 else 예약어를 사용하지 않았지만, 아직 좀 더 객체지향적으로 코드를 짤 필요가 있다고 느꼈다.

그래도 박재성님이 말씀하신 것처럼 일상생활 속에서 생각하며 코드를 작성하니 점차 들여쓰기가 줄어들고, 가독성은 증가하는 걸 느끼고 있다.


객체지향의 사실과 오해

https://prao.tistory.com/entry/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-2%EC%9E%A5-%EC%9D%B4%EC%83%81%ED%95%9C-%EB%82%98%EB%9D%BC%EC%9D%98-%EA%B0%9D%EC%B2%B4

 

[객체지향의 사실과 오해] 2장. 이상한 나라의 객체

객체지향의 예시 - 이상한 나라의 앨리스 컴컴한 굴 속의 천장이 낮은 긴 통로 위에 떨어진 앨리스. 커튼 뒤에 숨겨져 있던 작은 문을 발견했는데, 그 곳엔 아름다운 정원이 있다. 하지만 문의 높

prao.tistory.com

오늘은 객체지향의 사실과 오해 2장을 읽고 정리하였다.

이 책의 가장 큰 장점은 적절한 비유와 설명이다.

객체지향을 처음 접했을 때 바로 실전 코드를 보면서 무슨 말을 하는지 대충은 이해하였으나, 정확한 이해를 하지 못했었다.

객체지향의 사실과 오해라는 책을 보면서, 이상한 나라의 앨리스와 같이 이해하기 쉬운 비유들로 객체지향에 대해 보다 쉽게 이해할 수 있어서 큰 도움이 되는 책이다. 매일 조금씩 읽으면서 완독을 향해 나아가고 있다.

반응형
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...