개발자 Saaad
[JAVA] 백준 6단계 (심화 1) 5~8 문제풀이 본문
5. 1157번 단어 공부
- 주어진 문장에서 가장 많이 사용된 문자를 대문자로 출력하는 예제이다.
- 다만, 많이 등장한 알파벳이 여러개 존재하는 경우 ? 를 출력해야 한다.
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 str = br.readLine();
str = str.toUpperCase().trim();
// 배열을 생성하고 새로운 문자열을 만날 때, 배열에 저장
// 1개씩 돌면서 문자를 꺼내고, 배열의 인덱스를 증가시키며 카운트 1씩 증가
// 알파벳 배열
int[] arr = new int[26];
// -1로 초기화
for (int i = 0; i < 26; i++) {
arr[i] = -1;
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
int index = c - 'A';
// 이미 값이 존재하면
if (arr[index] != -1) {
arr[index]++;
} else {
arr[index] = 1;
}
}
int max = -1; // 초기값 -1
char ch = '?';
for (int i = 0; i < 26; i++) {
if (arr[i] > max) {
max = arr[i];
ch = (char)(i + 'A');
} else if (arr[i] == max) { // 갱신된 max값과 같으면 ? 출력
ch = '?';
}
}
System.out.print(ch);
}
}
- 입력받은 문자열을 toUpperCase() 로 대문자로 변환 후 trim()으로 양쪽 공백을 제거한다.
- 알파벳 배열 arr[] 을 선언하고 값을 -1로 모두 초기화한다.
- 입력한 문자열의 index번 째 문자를 순서대로 접근하여 char c 에 담는다.
- c(선택문자)- 'A' 를 하여 index 0 ~ 25까지 알파벳을 할당할 수 있도록 한다.
아래 아스키코드표를 확인해보면 'A' 는 아스키코드로 65번에 해당한다. 따라서 A~Z 중 문자를 A로 빼면 인덱스화 할 수 있다.
예를 들면 선택된 문자가 A라면 65 - 65 = 0 으로 index 값은 0이 될 것이고, 'B'는 66- 65기 때문에 index 1이 될 것이다.
- if문에서 arr[index] 값이 -1이 아니라면 값이 존재하는 상태이기 때문에 개수를 1개 증가시켜주면 된다.
- else문에 들어왔다면 arr[index] 값이 -1 이었기 때문에 값이 없었던 상태, 즉 최초 그 문자가 등장했기 때문에 값을 1로 저장해주면 된다.
- max 값과 출력되어야하는 문자 ch를 선언한다.
- for문에 들어가 max값을 업데이트하고, ch는 'A' 를 더해주고 char로 형변환을 하여 원래 대문자 알파벳이 나올 수 있도록 한다.
- else if에서는 기존 max값과 arr[index] 값이 일치하면 여러 개의 많이 사용된 알파벳이 존재하는 것이기 때문에 ch에 '?' 을 할당한다.
- 결과가 출력된다.
6.2941번 크로아티아 알파벳
- 특정 문자열이 등장할 때마다 개수를 1개씩 증가시킨 값을 출력하면 된다.
- c= , c- , dz= .. 등 문자열이 나올 때마다 카운팅하면 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char ch;
int count = 0;
String st = br.readLine();
// ljes=njak
for(int i=0; i < st.length(); i++){
ch = st.charAt(i);
if(i < st.length()-1 && ch == 'c'){
if( st.charAt(i+1) == '=') i++;
else if(st.charAt(i+1) == '-' ) i++;
}
else if( i < st.length()-1 && ch == 'd'){
if(i < st.length()-2 && st.charAt(i+1) == 'z'){
if(st.charAt(i+2) == '='){
i+=2;
}
}
else if( st.charAt(i+1) == '-'){
i++;
}
}
else if(i < st.length()-1 && ch == 'l'){
if(st.charAt(i+1) == 'j') i++;
}
else if( i < st.length()-1 && ch == 'n'){
if( st.charAt(i+1) == 'j') i++;
}
else if( i < st.length()-1 && ch == 's'){
if( st.charAt(i+1) == '=') i++;
}
else if( i < st.length()-1 && ch == 'z'){
if( st.charAt(i+1) == '=') i++;
}
count++;
}
System.out.print(count);
}
}
- 무자비한 if문으로 코드를 풀었다.
- 입력받은 문자열을 1개씩 for문을 통해 순회하며 중첩 if문을 통해 해결하였다.
다른 접근법 (String의 contains() )
아래는 같이 스터디를 진행하는 팀원이 작성한 코드인데 내 코드보다 낫고 참신한 접근인 것 같아서 소개한다.
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] croatia = {"c=","c-","dz=","d-","lj","nj","s=","z="};
String input = br.readLine();
for (int i = 0; i < croatia.length; i++) {
if (input.contains(croatia[i])){
input = input.replace(croatia[i], "H");
}
}
System.out.println(input.length());
}
}
- 내 코드와 달리 크로아티아 문자열을 배열에 저장해두었다.
- 입력받은 문자열에 크로아티아 배열의 값들에 순차적으로 접근하며 각 문자열이 존재하면 기존 문자열을 H로 대체한다.
- 대체된 문자열의 길이를 출력하면 끝이다.
- 매우 매우 코드가 간단해진다!!!!
shout out s2ej1n
아래 링크로 가면 더 자세한 설명이..
https://s2ej1n.tistory.com/103
[백준/Java] 2941 크로아티아 알파벳 / 25206 너의 평점은 (백준 단계별로 풀기 6단계 심화1)
백준 단계별로 풀기 6단계 - 심화1후다닥 간단하게 푼 문제들만 모아보았다.자바8과 자바 11을 통해 풀어보았다.2941 크로아티아 (자바8 68ms / 자바11 104ms) ✏️ 자바 코드크로아티아 알파벳중 H는
s2ej1n.tistory.com
7. 1316 그룹 단어 체커
- 단어 N개를 입력받고 그룹 단어에 해당하는 단어들의 개수를 출력하는 문제이다.
- 그룹단어란 'aabb' 처럼 각 문자가 연속해서 나타나는 경우만을 이야기한다.
- 'aba', 'aaabbbcca' 같이 a가 이전에 등장했었다면, a가 또 나오면 이 조건을 위반하게 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
int count = 0;
int num = Integer.parseInt(br.readLine()); // 입력한 단어의 개수
for (int i = 0; i < num; i++) {
if (check() == true)
count++;
}
System.out.print(count);
}
public static boolean check() throws IOException {// aabbcc
boolean[] check = new boolean[26];
int prev = 0;
String str = br.readLine(); // 문자열 입력
for (int i = 0; i < str.length(); i++) {
int now = str.charAt(i); // i번째 문자 저장
// 앞선 문자와 i번째 문자가 같지 않다면?
if (prev != now) {
// 해당문자가 처음 나오는 경우
if (check[now - 'a'] == false) {
check[now - 'a'] = true; // 문자 등장여부 true로 변경
prev = now; // 현재 단어를 prev에 저장
}
// 해당 문자가 이미 나온 적이 있다면(그룹단어 x)
else {
return false;
}
}
}
return true;
}
}
- check() 메소드를 생성하였다.
- check() 는 각 입력받은 문자열에 대해서 그룹 단어인지 판별하는 함수이다.
- prev 변수의 초기값을 0으로 저장하고 now 변수를 이용해 for문에서 차례대로 문자에 접근하게 된다.
- if(check[now - 'a'] == false 인 경우, 앞에서 check 배열을 초기화해두었기 때문에 해당 문자가 처음 나온 경우가 된다.
등장 여부를 변경하기 위해 true로 변경하고 prev를 업데이트한다. - if(check[now - 'a'] == true 인 경우, 이미 등장했던 문자가 또 등장한 것이다. 그룹단어에 해당하지 않게 되기 때문에
return false; 를 통해 for문을 종료시킨다. - check() 메소드가 종료되면 true 또는 false를 반환하며 main() 에서 count를 증가시키거나 아무것도 하지않게 된다.
- 그룹 단어의 개수가 출력된다 .
8. 25206 너의 평점은
- 치훈이의 전공학점을 계산하되, P학점은 계산에서 제외하며 계산해야한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String [] gradeString = {"A+", "A0", "B+", "B0", "C+", "C0", "D+", "D0", "F"};
double [] grades = {4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.0 , 0.0};
double scoreSum = 0.0;
double totalSum = 0.0;
for (int i = 0; i < 20; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
String subject = st.nextToken();
double score = Double.parseDouble(st.nextToken());
String grade = st.nextToken(); // A+ B+..
// 등급이 P면 계산에서 제외
if(grade.equals("P")) continue;
scoreSum += score; // 학점의 총합 계산
for (int j = 0; j < grades.length; j++) {
if(grade.equals(gradeString[j])) {
totalSum += score * grades[j]; // 학점 x 과목평점 (전공평점의 총 합)
}
}
}
System.out.printf("%.6f",(double)totalSum / scoreSum);
}
}
- 과목 평점 (A+, A0 , ... ) 배열 gradeString[]과 같은 순서로 저장되어 있는 학점 배열 grades[] 를 초기화한다.
- 실수 단위의 계산이기 때문에 double로 변수들(scoreSum, totalSum)을 선언한다.
scoreSum은 학점의 합을 저장하는 변수이고 totalSum은 각 전공의 (학점 * 과목 평점) 값을 합을 저장하는 변수이다. - StringTokenizer 객체 st를 이용해 전공 이름, 점수, 과목 평점을 입력받는다
- 만약 등급이 P라면 continue를 통해 다음 for문으로 이동한다.
- 입력받은 점수를 scoreSum에 더해준다 ( 학점의 총합 계산)
- for문을 돌며 입력받은 grade( A+, A0 ... ) 와 기존 배열의 값을 비교해 일치하는 인덱스의 위치를 찾아낸다.
- 해당 인덱스 j 값을 이용해 grades[j] 에 접근하여 과목 평점에 매칭되는 점수를 구하고 totalSum을 업데이트 한다.
- 원하는 소수점만큼 출력하기 위해 printf()를 사용한다.
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[JAVA] 백준 7단계 (2차원 배열) 문제 풀이 (0) | 2025.01.24 |
---|---|
[JAVA] 백준 6단계 (심화 1) 문제 풀이 (4번까지) (1) | 2025.01.22 |
[JAVA] 백준 5단계 (문자열) 문제 풀이 (0) | 2025.01.21 |
[JAVA] 백준 4단계 (1차원 배열) 문제 풀이 (1) | 2025.01.20 |
[JAVA] 백준 3단계(반복문) 문제 풀이 (0) | 2025.01.15 |