풀이
첫 풀이
- 문자열을 “ “ 띄어쓰기 단위로 잘라서 (StringTokenizer 사용) → word 단위로 만듬
- 띄어쓰기 없이 잘라진 것에서 그 길이만큼의 반복문 안에서
- tag 안에 있는 것인지 밖에 있는 것인지 구별하여
- tagBuilder나 reverse라는 스택 안에 넣어주는 방식으로 풀이
- 자세한 사항// > 로 끝났을 때 tag가 끝난 것이기 때문에 tagBuilder에 쌓인 값 answer에 넣어주기
package etc; import java.io.*; import java.util.*; public class Main_17413 { public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String S = br.readLine(); StringTokenizer st = new StringTokenizer(S); StringBuilder answer = new StringBuilder(); // 전체 정답 문장 StringBuilder tagBuilder = new StringBuilder(); // 올바르게 들어갈 <> tag안의 문장. 띄어쓰기 포함 가능해서 다음 word에 있는 값이 있을 수도 있음 boolean tag = false; // 현재 tag가 열려있는지 여부. true의 값이면 > 가 아직 없음 while(st.hasMoreTokens()){ String word = st.nextToken(); Stack<Character> reverse = new Stack<>(); // 거꾸로 될 문장 for (int i = 0; i < word.length(); i++) { if(word.charAt(i) == '<'){ tag = true; int s = reverse.size(); for (int j = 0; j < s; j++) { answer.append(reverse.pop()); } } else if (word.charAt(i) == '>') { tag = false; tagBuilder.append(word.charAt(i)); answer.append(tagBuilder); tagBuilder = new StringBuilder(); // 비우기 이렇게 가능? continue; } if(tag){ tagBuilder.append(word.charAt(i)); }else{ reverse.push(word.charAt(i)); } } if(tag){ // tag가 진행중인데 한 word가 끝난 경우는 사이에 띄어쓰기가 있는 것이므로 넣어주기 tagBuilder.append(" "); } int s = reverse.size(); for (int i = 0; i < s; i++) { answer.append(reverse.pop()); } if(answer.length()!=0 && !tag && st.hasMoreTokens()){ answer.append(" "); } } System.out.println(answer.toString()); } }
- // < 나 >는 아니지만 tag안에 있는 경우는 tagBuilder에 넣기 // < 나 >는 아니지만 tag밖에 있는 경우는 reverse에 넣기
- // < 로 시작했을 때 그 이전에 reverse 스택에 쌓인 것 answer에 넣어주기 여기서는 " " 를 넣지 않음(태그와 단어 사이에 띄어쓰기가 없음)
→ 계속 ‘출력 형식이 잘못되었습니다’ 라고 떠서 반례를 찾아 헤매다
공백이 <> 태그안에 여러개가 있는 경우를 생각함..
태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.
이 문장에서 보면 태그 안은 단어가 아니기 때문에 공백이 여러번 들어갈 수 도 있다. ㅎ……………………..
+진짜 바보인가..문제에 있는 예제 7번에 그런 케이스도 말해줬었는데 못봄..
→ 처음부터 다시 접근해야함^^
두번째 풀이
문자열 길이 S.length() 만큼 for문을 돌면서
- < > 안은 tagBuilder 에 넣어서
- answer에 추가해준다.
- < > 밖은 reverse 스택에 넣어서 - 공백이 나올 때 까
- answer에 추가해준다.
코드
package etc;
import java.io.*;
import java.util.*;
public class Main_17413 {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String S = br.readLine();
StringBuilder answer = new StringBuilder(); // 전체 정답 문장
StringBuilder tagBuilder = new StringBuilder(); // 올바르게 들어갈 <> tag안의 문장. 띄어쓰기 포함 가능해서 다음 word에 있는 값이 있을 수도 있음
boolean tag = false; // 현재 tag가 열려있는지 여부. true의 값이면 > 가 아직 없음
Stack<Character> reverse = new Stack<>(); // 거꾸로 될 문장
for (int i = 0; i < S.length(); i++) {
if(S.charAt(i) == '<') {
tag = true;
while (!reverse.isEmpty()) {
answer.append(reverse.pop());
}
} else if (S.charAt(i) == '>') {
tag = false;
tagBuilder.append(S.charAt(i));
answer.append(tagBuilder);
tagBuilder = new StringBuilder();
continue;
}
if(tag) {
tagBuilder.append(S.charAt(i));
} else {
if(S.charAt(i) == ' ' || i == S.length()-1) {
if(i == S.length()-1){
reverse.push(S.charAt(i));
}
while (!reverse.isEmpty()) {
answer.append(reverse.pop());
}
answer.append(" ");
} else {
reverse.push(S.charAt(i));
}
}
}
System.out.println(answer);
}
}
참고
- 참고 코드
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s = sc.nextLine(); StringBuilder sb = new StringBuilder(); int i = 0; int j = i; while(i<s.length()) { if(s.charAt(i)=='<') { j = i; while(i<s.length()&&s.charAt(i)!='>')i++; sb.append(s.substring(j, ++i)); }else if(s.charAt(i)!=' ') { j = i++; while(i<s.length() &&s.charAt(i)!=' '&&s.charAt(i)!='<')i++; for (int k = i-1; k >= j; k--) { sb.append(s.charAt(k)); } }else if(s.charAt(i++)==' ') sb.append(" "); } System.out.println(sb); } }
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuilder sb = new StringBuilder();
int i = 0;
int j = i;
while(i<s.length()) {
if(s.charAt(i)=='<') {
j = i;
while(i<s.length()&&s.charAt(i)!='>')i++;
sb.append(s.substring(j, ++i));
}else if(s.charAt(i)!=' ') {
j = i++;
while(i<s.length() &&s.charAt(i)!=' '&&s.charAt(i)!='<')i++;
for (int k = i-1; k >= j; k--) {
sb.append(s.charAt(k));
}
}else if(s.charAt(i++)==' ') sb.append(" ");
}
System.out.println(sb);
}
}
'공부 > 알고리즘' 카테고리의 다른 글
[백준]20413_MVP 다이아몬드 (Easy)_그리디 Java 풀이 (0) | 2023.02.14 |
---|---|
[백준]1916_최소비용 구하기_다익스트라 인접행렬, 인접리스트 Java풀이 + 반례 (0) | 2023.02.08 |
[프로그래머스]42576_완주하지 못한 선수_Java 풀이 2가지 (0) | 2023.01.25 |
[백준]1018_체스판 다시 칠하기_Java 풀이 (1) | 2023.01.24 |
[백준]2751_수 정렬하기2_Java풀이(Collections.sort, Counting Sort) (0) | 2023.01.10 |
댓글