[단계별로 풀어보기-Java] 6단계 심화1
안녕하세요 ~
오늘은 6단계 심화1 문제 푸는 날입니다 !
✏️ 문제 번호 : 25083
새싹
public class Main {
public static void main(String[] args) {
System.out.println(" ,r'\"7");
System.out.println("r`-_ ,' ,/");
System.out.println(" \\. \". L_r'");
System.out.println(" `~\\/");
System.out.println(" |");
System.out.println(" |");
}
}
✏️ 문제 번호 : 3003
킹, 퀸, 룩, 비숍, 나이트, 폰
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int[] list = {1,1,2,2,2,8};
for(int i=0;i<input.length;i++){
int diff = list[i] - Integer.parseInt(input[i]);
System.out.print(diff + " ");
}
}
}
풀이 과정
정해진 체스 말 개수를 list로 배열을 정해줍니다.
그 후, 입력 값을 배열에 빼주면
입력 값에 따라 각 체스 말의 부족하거나 초과된 개수를 출력할 수 있습니다.
✏️ 문제 번호 : 2444
별 찍기 - 7
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
StringBuilder sb = new StringBuilder();
// 위쪽 삼각형
for (int i = 1; i <= N; i++) {
sb.append(" ".repeat(N - i));
sb.append("*".repeat(2 * i - 1));
sb.append("\n");
}
// 아래쪽 삼각형
for (int i = N - 1; i >= 1; i--) {
sb.append(" ".repeat(N - i));
sb.append("*".repeat(2 * i - 1));
sb.append("\n");
}
System.out.print(sb.toString());
}
}
String.repeat() 메서드는 Java 11 이상에서만 지원되므로
이번 코드는 Java 11언어를 사용했습니다.
✏️ 문제 번호 : 10988
팰린드롬인지 확인하기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
boolean b = true;
for(int i=0;i<s.length();i++){
if((s.charAt(i) != s.charAt(s.length()-i-1))){
b = false;
break;
}
}
System.out.println(b ? 1 : 0);
}
}
코드 설명
먼저, 팬린드롬 여부 확인을 위해 boolean 논리 변수를 true라고 가정합니다.
문자열 앞뒤를 비교하기 위해, for문을 사용했고
앞뒤 문자가 다를 시 false로 바꿔줍니다.
그 후, 삼항연산자를 사용해서 결과를 출력해줬습니다.
✏️ 문제 번호 : 1157
단어 공부
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
int[] arr = new int[26]; //영문자 개수는 26개
int c = System.in.read();
while (c > 64){ //공백을 입력 받으면 종료됨
if(c<91){
arr[c-65] ++; //해당 인덱스의 값 1 증가
}
else{ //소문자 범위
arr[c-97] ++;
}
c = System.in.read();
}
int max = -1;
int ch = -2; //?는 63이다.
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
ch = i;
}
else if (arr[i] == max){
ch = -2;
}
}
System.out.print((char)(ch+65)); // 대문자로 출력해야하므로 65을 더해줌.
}
}
코드 설명
1. 입력 받기
알파벳(A-Z)의 빈도를 저장하기 위해, 26의 값을 배열에 넣었고
위 문제는 문자열만 입력받기 때문에 BufferedReader가 필요 없기 때문에, System.in.read()로 입력을 받았습니다.
2. 알파벳 빈도 계산하기
대문자 범위가 65~90 이므로 if(c<91)에서 65을 빼주고,
소문자 범위가 97 ~ 122 이므로 97을 빼줍니다.
3. 최대 빈도와 문자 찾기
max에 가장 많이 사용된 알파벳 빈도를 저장했고, 초기값은 -1로 설정했습니다.
ch는 최대 빈도를 가진 알파벳의 인덱스를 저장하고, 중복될 경우 -2로 설정하여 ?를 출력합니다.
참고로 ASCII코드 63은 문자 ?에 해당합니다.
if (arr[i] > max) { // 현재 알파벳의 빈도가 최대값을 초과하면
max = arr[i]; // max와 ch를 갱신
ch = i; // 현재 알파벳의 인덱스를 저장
} else if (arr[i] == max) { // 현재 알파벳의 빈도가 기존 최대값이 같음
ch = -2; // 빈도가 같으면 '?'로 설정
}
✏️ 문제 번호 : 2941
크로아티아 알파벳
문제 살펴보기
크로아티아 알파벳은 위 문제 표와 같이 8개가 있습니다.
표를 참고해서 입력값에 해당하는 크로아티아 알파벳과 크로아티아 알파벳이 아닌 알파벳이 몇 개가 있는지
출력하는 문제입니다.
예를 들어,
ljes=njak은 알파벳 6개(lj, e, š, nj, a, k)로 이루어져 있습니다.
c=c=는 알파벳 2개(c=, c=)로 이루어져 있습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String[] croAlpa = {"c=","c-","dz=","d-","lj","nj","s=","z="};
String alpaInput=br.readLine();
// 크로아티아 알파벳 개수 계산
int count = 0;
for (String cro : croAlpa) {
while (alpaInput.contains(cro)) {
count++; // 크로아티아 알파벳 개수 증가
alpaInput = alpaInput.replaceFirst(cro, " "); // 크로아티아 알파벳 제거
}
}
// 남은 문자의 개수 추가
alpaInput = alpaInput.replace(" ", ""); // 공백 제거
count += alpaInput.length(); // 남은 문자 개수 추가
System.out.println(count);
}
}
코드 설명
1. 입력 받기
크로아티아 알파벳 배열 목록을 만들어 줍니다.
2. 크로아티아 알파벳 개수 계산
크로아티아 알파벳 발견 시 바로 count가 증가합니다.
replaceFirst를 사용하면 크로아티아 알파벳을 하나씩 대체하므로 간단하게 처리할 수 있습니다.
3. 남은 문자 개수 추가
크로아티아 알파벳 제거를 하면 생긴 공백 " "을 replace를 통해 공백 제거 과정을 거칩니다.
그 후, 남은 기존 알파벳 개수를 추가합니다.
왜 replaceFirst를 사용했을까요?
먼저, replace와 replaceFirst, replaceAll에 대해 알려드리겠습니다.
메서드 | 설명 | 정규 표현식 지원 | 동작 방식 |
replace | 문자열의 모든 매칭된 부분을 대체. | ❌ (정규 표현식 지원 안 됨) | 정확한 문자열 대체 |
replaceFirst | 문자열의 첫 번째 매칭된 부분만 대체. | ✅ (정규 표현식 지원) | 첫 번째 매칭만 대체 |
replaceAll | 문자열의 모든 매칭된 부분을 대체. | ✅ (정규 표현식 지원) | 정규 표현식으로 매칭된 모든 부분 대체 |
replaceAll 메서드를 사용하게 된다면,
크로아티아 알파벳 문자열 중 일부 '='와 같은 문자가 특수 문자로 표현하고 있기에
이를 제대로 처리하지 못하게 되고, 에러나 잘못된 동작이 발생할 수 있습니다.
그래서, replaceFirst 메서드를 사용하면,
단순 문자열로 동작하기 때문에 정규 표현식을 신경쓰지 않아도 됩니다.
만약에
replaceAll을 꼭 사용하고 싶다면,
특수 문자를 이스케이프 처리해야합니다.
Pattern.quote()를 사용하면 간단히 해결됩니다.
alpaInput = alpaInput.replaceAll(Pattern.quote(cro), " ");
하지만, replaceAll을 적용해봤지만 에러가 떴습니다.
replaceFirst메서드 사용을 하시길 바랍니다 !
✏️ 문제 번호 : 1316
그룹 단어 체커
문제 살펴보기
위 문제를 풀기 전,
그룹단어 뜻에 대해 정확히 짚고 넘어가야 한다.
그룹 단어란?
어떤 단어가 연속해서 등장하는 문자들로만 이루어진 경우
한 문자가 끊겼다가 다시 등장하면 그룹 단어가 아님
aba단어에서, ab단어에 a가 다시 등장했으므로, 그룹 단어가 아니고
abab에서 a와 b가 번갈아 다시 등장했으므로, 그룹 단어가 아닙니다.
하지만, 단일 단어 a만 입력 받는다면 그룹 단어입니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int input = Integer.parseInt(br.readLine());
int count = 0; // 그룹 단어 개수 초기화
for (int i = 1; i <= input; i++) {
String str = br.readLine();
if (groupWord(str)) {
count++;
}
}
System.out.println(count); // 최종 그룹 단어 개수 출력
}
public static boolean groupWord(String str) {
int[] visited = new int[26]; // 알파벳 방문 여부를 0으로 초기화
char prev = ' '; // 이전 문자 초기화
for (int i = 0; i < str.length(); i++) {
char curr = str.charAt(i); // 현재 문자
int idx = curr - 'a'; // 알파벳 인덱스 계산
if (curr != prev) { // 이전 문자와 다를 경우(= 새로운 문자가 나타남!)
if (visited[idx] > 0) { // 현재 문자가 이미 방문한 알파벳이라면 그룹 단어 아님
return false; // 그룹 단어가 아님
}
visited[idx] = 1; // 현재 문자 방문 처리
}
prev = curr; // 이전 문자를 현재 문자로 업데이트
}
return true; // 그룹 단어일 경우
}
}
✏️ 문제 번호 : 25206
너의 평점은
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
double total=0.0;
double sum=0.0;
String[] gradeScale = {"A+", "A0", "B+", "B0", "C+", "C0", "D+", "D0", "F"};
double[] gradeValues = {4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.0, 0.0};
for (int i = 0; i < 20; i++) {
String line = br.readLine();
String[] data = line.split(" ");
double credit = Double.parseDouble(data[1]); //학점
String grade = data[2]; //등급
if (!grade.equals("P")) { // Pass 과목은 포함안함
for (int j = 0; j < gradeScale.length; j++) {
if (grade.equals(gradeScale[j])) {
total += credit; // 총 학점
sum += credit * gradeValues[j]; // (학점 * 등급 점수)
break;
}
}
}
}
double gpa = total == 0 ? 0.0 : sum / total;
System.out.printf("%.6f", gpa);
}
}
코드 설명
우선, 20줄을 입력 받아야하며
등급과 학점은 gradeScale, grageValues 두 배열을 사용했습니다.
등급이 P인 과목은 제외하고, 총 학점(total)과 학점*등급점수(sum)을 계산합니다.
그 후, 전공평점을 출력해야하므로
(총 학점 * 등급 점수) / 총 학점으로 계산했습니다.
만약, 총 학점이 0이면 0.0을 출력합니다.
이번 백준 6단계를 이틀을 거쳐 문제를 여유롭게 풀어봤습니다 ~
점점 문제들이 어려워지고 있네요 ㅜ
다음 단계도 화이팅 !!!