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

 

17413번: 단어 뒤집기 2

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져

www.acmicpc.net

문제 풀이 (JAVA)

import java.util.Scanner;
import java.util.Stack;

public class Main {

	public static void main(String[] args) {
		// 단어 뒤집기2
		Scanner input = new Scanner(System.in);

		String str = input.nextLine();
		String result = solution(str);
		System.out.print(result);
	}

	public static String solution(String s) {
		StringBuilder answer = new StringBuilder();
		Stack<Character> stack = new Stack<>();
		boolean flag = false; // tag가 아닐때 false
		for (int i = 0; i < s.length(); i++) {
			char ch = s.charAt(i);
			if (ch == '<') {
				flag = true; // tag일때 true
				// 태그전에 들어온 글자가 있을경우 스택 출력
				while (stack.isEmpty() != true) {
					answer.append(stack.pop());
				}
				answer.append(ch); // '<' 추가
				continue;
			} else if (ch == '>') {
				flag = false; // '>' 일때 tag가 종료됨을 알림
				answer.append(ch);
				continue;
			}
			// tag가 종료됬으나 tag 밖 글자가 공백을 가진다면 공백을 기준으로 역순출력해야하므로
			else if (flag == false && ch == ' ') {
				flag = false;
				// 스택에 들어온 값 역순 출력
				while (stack.isEmpty() != true) {
					answer.append(stack.pop());
				}
				answer.append(ch); // ' ' 추가
				continue;
			}
			if (flag == true) { // tag 안이라면
				answer.append(ch); // 정상출력
			} else if (flag == false) { // tag 밖이라면
				stack.push(ch); // 역순출력을 위한 스택 추가
				// 마지막 행 처리(index가 마지막이면 종료하므로.)
				if (i == s.length() - 1) {
					while (stack.isEmpty() != true) {
						answer.append(stack.pop());
					}
				}
			}

		}
		return answer.toString();
	}
}

다른 사람 풀이 코드(JAVA)

import java.io.*;
import java.util.*;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " <>", true);
		StringBuilder answer = new StringBuilder();

		boolean flag = false;
		while (st.countTokens() > 0) {
			String token = st.nextToken();
			if (token.equals("<"))
				flag = true;
			else if (token.equals(">"))
				flag = false;

			if (flag)
				answer.append(token);
			else {
				StringBuilder tmp = new StringBuilder(token);
				answer.append(tmp.reverse());
			}
		}
		System.out.println(answer);
	}
}

주요 핵심 포인트

1. 해당 문제는 <tag> 일때 boolean 논리변수를 설정해주는 것이 가장 중요하다. 따라서 tag일때에는 정상 출력을 해야하므로 true, tag가 아닐때에는 스택에 쌓은 순서로 출력해야 하므로 false 논리변수를 설정한다.

2. '<' 가 들어왔을때 논리 변수를 tag임을 알리는 true로 변경하며, 스택에 값이 들어있다면 '<' 괄호 이전에 false로 설정되어 스택이 쌓였다는 의미로 스택이 있는 경우에는 먼저 값을 출력한 후 추가한다.

3. '>'가 들어왔을때 논리 변수를 tag가 아님을 알리는 false로 변경하며, 이후 문자를 스택에 저장한다.

4. '    '  공백의 경우, tag안의 글자 사이에 공백이 있거나, tag 밖 글자에 공백이 있을수 있으므로, tag 밖 글자가 공백일 경우에만 역순으로 출력한다.

5. 마지막 인덱스에서는 push()만 하고 종료될수 있으므로 , 마지막 인덱스일경우 스택의 모든 문자를 출력한다!! 처리 하지 않으면 마지막 문자가 나오지 않는다.

 

개선해야할 사항

1. 해당 문제는 풀지 못하여 다른 사람의 코드를 참조한 후, 다시 풀어보았다. 해당 문제를 풀지 못한 이유는 생각을 너무 짧게 하고 코딩에 돌입해서 그런듯 하다. 한번 꼬이기 시작하면 머리가 하애지기 때문에 사전에 로직을 어떻게 처리할지 머리속으로 충분히 정리한 후 구현하는 연습을 해야 할듯 하다. 다음부터는 정리를 다 끝내고 코딩을 해야겠다.

2. 다른 사람이 푼 코드는 StringTokenizer 생성자 함수에 구분자를 정규식처럼 사용하여 나누었다. 해당 코드는 스페이스바, < , >   3가지를 기준으로 구분하여 저장하겠다는 생성자 함수이다. 해당 식을 통해 '<' , '문자열', '>' 를 token으로 받아 쉽게 처리 할수 있음을 볼 수 있다. 또한 StringBuilder를 통해 .reverse() 함수를 사용하여 역순 정렬을 처리하였다. 해당 코드가 가장 클린한 코드로 보이며, 해당 코드 또한 참조할줄 알아야겠다.

'백준(JAVA)' 카테고리의 다른 글

[백준 2583번] 영역 구하기  (0) 2023.02.12
[백준 11403번] 경로 찾기  (0) 2023.02.10
[백준 1806번] 부분합  (0) 2022.12.04
[백준 1260번] DFS와 BFS  (0) 2022.12.04
[백준 1913번] 달팽이  (0) 2022.08.15

String
str.toLowerCase(); // 문자열을 소문자로 바꾼다.
str.toUpperCase(); // 문자열을 대문자로 바꾼다.

str.charAt(i);// 문자열 str의 i번째 인덱스의 문자를 가져온다.

str.toCharArray(); // String 문자열을 char 문자배열로 바꾼다.

str.split(""); // 구분자 파라미터를 기준으로 String을 String 배열로 변경한다.

str.equals(b); // b와 str의 문자열이 같은지 여부를  boolean으로 반환한다.

str.indexOf("s"); // 문자 s의 인덱스가 몇번째인지를 반환한다. 

str.substring(N); //  문자열의 인덱스 N번째부터 마지막 인덱스까지의 문자열을 가져온다.

str.substring(N,K); // 문자열 인덱스 N부터 K-1번째까지의 문자열을 가져온다.

new StringBuilder(str).reverse().toString(); //  문자열 str을 배열로 StringBuilder 배열로 재정의 후 reverse()로 역순정렬 , toString()으로 다시 문자열로 복원한다. (문자열 역순 정렬 필요시 사용)

str.equalsIgnoreCase(tmp); // tmp 문자를 대소문자 구분 안하고 알파벳을 비교한다.

str.replaceAll("[^A-Z]",""); // A~Z가 아닌 특수문자들을 공백으로 치환한다.

String.valueOf(N) // int 형의 N을 문자열로 변환한다. 

 

Character

Character.toUpperCase(ch); // 문자 ch를 대문자로 변경한다.

char ch = in.next().charAt(0); // Scanner로 입력받은 String의 첫번째 글자를 char 문자로 가져온다.

Character.isLowerCase(ch))  // ch가 소문자인지 여부를 true or false로 반환한다.
Character.isUpperCase(ch))  // ch는 대문자인지 여부를 true or false로 반환한다.

Character.isDigit(ch) // 문자 ch가 숫자인지를 true or false로 반환한다.

Character.getNumericValue(ch) // 문자 ch를 숫자로 변환한다.

Character.isAlphabetic(ch) // 문자 ch가 알파벳이면 true 아니면 false를 반환한다.

 

Integer

Integer.parseInt(str) // 문자열 str을 Int로 변환한다.

Integer.parseInt(tmp,2) // 2진수 문자열 tmp를 10진수로 변환한다.

Integer.toString(7); // 숫자 7을 String "7"로 변환한다.

Integer.toLong(3); // 숫자 3을 Long 타입 3으로 변환한다.

Integer.toBinaryString(3 | 5); // 비트연산자 '|' 는 두 숫자 3,5의 2진수비트를 OR 연산하여 만들어진 숫자를 문자열로 저장한다.

'JAVA 라이브러리' 카테고리의 다른 글

List , Set , Collections 정렬 함수 정리  (0) 2022.06.27
스택 + 큐 함수 정리  (0) 2022.06.26
HashMap 함수 정리  (0) 2022.06.19

+ Recent posts