728x90
반응형
2024년 2회 정보처리기사 실기 기출문제
문제
다음 Java 코드를 실행했을 때 출력 결과를 쓰시오.
class Main {
public static void main(String[] args) {
String str = "abacabcd";
boolean[] seen = new boolean[256];
System.out.print(calculFn(str, str.length() - 1, seen));
}
public static String calculFn(String str, int index, boolean[] seen) {
if (index < 0) return "";
char c = str.charAt(index);
String result = calculFn(str, index - 1, seen);
if (!seen[c]) {
seen[c] = true;
return c + result;
}
return result;
}
}
정답
dcba
반응형
해설
1️⃣ main
public static void main(String[] args) {
String str = "abacabcd";
boolean[] seen = new boolean[256];
System.out.print(calculFn(str, str.length() - 1, seen));
}
public static void main(String[] args) {
- 프로그램의 진입점인 main() 메서드입니다.
String str = "abacabcd";
- 문자열 str에 "abacabcd"를 저장합니다.
- 이 문자열의 각 문자에 대해 중복 여부를 검사하고, 결과 문자열을 만들게 됩니다.
boolean[] seen = new boolean[256];
- seen이라는 이름의 boolean 타입 배열입니다.
- boolean은 참(true) 또는 거짓(false)의 값을 가지는 자료형입니다.
- 배열의 크기를 256으로 설정한 이유는 바로 ASCII 문자 체계 때문입니다. ASCII(아스키)는 문자를 숫자로 표현하는 규칙이고, 총 256개(0 ~ 255)의 문자 코드가 정의되어 있습니다. 즉, 모든 ASCII 문자(영문자, 숫자, 특수문자 포함)를 다룰 수 있도록 배열 크기를 256으로 설정한 것입니다.
- 'a' → ASCII 코드 97
- 'A' → ASCII 코드 65
- '0' → ASCII 코드 48
- '!' → ASCII 코드 33 등
- Java에서 boolean[] 배열을 생성하면, 모든 요소가 자동으로 false로 초기화됩니다.
System.out.print(calculFn(str, str.length() - 1, seen));
- calculFn()을 호출하고 결과를 출력합니다.
- str : 문자열 "abacabcd"입니다. 이 문자열을 한 글자씩 분석하기 위해 전달합니다.
- str.length() - 1 : str.length()는 문자열의 길이 → "abacabcd"는 8글자 → 8, - 1을 하면 7
- seen : boolean[] seen = new boolean[256]; 배열, 각 문자의 등장 여부를 저장해두는 배열입니다.
728x90
2️⃣ calculFn
public static String calculFn(String str, int index, boolean[] seen) {
if (index < 0) return "";
char c = str.charAt(index);
String result = calculFn(str, index - 1, seen);
if (!seen[c]) {
seen[c] = true;
return c + result;
}
return result;
}
public static String calculFn(String str, int index, boolean[] seen) {
- calculFn() 함수 정의
- 매개변수:
- str: 원본 문자열
- index: 현재 검사할 문자 위치
- seen: 중복 체크용 배열
- 매개변수:
if (index < 0) return "";
// 기본형
if (index < 0) {
return "";
}
- Java의 if 문은 일반적으로 중괄호 {}를 사용합니다. 조건이 참일 경우 return "" 문장을 실행합니다.
- 조건문 다음에 실행할 코드가 딱 한 줄일 경우, 중괄호 {}를 생략할 수 있습니다.
- index가 0보다 작아지면 재귀 호출을 멈추는 종료 조건(base case)입니다.
char c = str.charAt(index);
// charAt 메서드 : 문자열(String)의 특정 위치에 있는 문자 하나를 가져오는 메서드
char c = 문자열.charAt(인덱스);
- 문자열: "hello" 같은 String 객체
- 인덱스: 가져오고 싶은 문자 위치 (0부터 시작)
- 반환값: char 타입 (한 글자)
- 현재 인덱스에 해당하는 문자를 꺼냅니다.
- 예: index = 7이면 str.charAt(7) → 'd'
String result = calculFn(str, index - 1, seen);
- 현재 함수 안에서 자기 자신을 다시 호출하고 있습니다. (재귀 호출)
- 재귀 호출이 완료되면, 그 결과 문자열을 result에 저장합니다.
- calculFn 함수가 처음 호출될 때 인자 값
- str = "abacabcd"
- index = str.length() - 1 : str.length()는 문자열의 길이 → "abacabcd"는 8글자 → 8, - 1을 하면 7
- seen = new boolean[256]. 모든 값이 false인 boolean 배열입니다.
3️⃣ 함수 작동 원리
public static String calculFn(String str, int index, boolean[] seen) {
if (index < 0) return ""; // base case
char c = str.charAt(index);
String result = calculFn(str, index - 1, seen); // 재귀 호출
if (!seen[c]) {
seen[c] = true;
return c + result;
}
return result;
}
🎯 목표
문자열을 오른쪽부터 왼쪽으로 탐색하면서 중복되지 않은 문자만 남기는 재귀함수 :
문자열 "abacabcd"를 뒤에서부터 한 글자씩 보면서, 중복되지 않은 문자만 남기기. 그리고 그 문자를 뒤에서 처음 등장한 순서로 이어붙이는 것.
🎯 재귀 함수의 흐름
- 주어진 문자열: "abacabcd"
문자 : a b a c a b c d
인덱스: 0 1 2 3 4 5 6 7
1. index가 음수인지 확인
if (index < 0) return "";
- base case: 종료 조건입니다. index가 0 이상이면 다음 단계로 진행합니다.
- index = str.length() - 1 : str.length()는 문자열의 길이 → "abacabcd"는 8글자 → 8, - 1을 하면 7
- 따라서 종료 조건에 해당하지 않기 때문에 다음 단계로 진행
2. 현재 문자 꺼내기
char c = str.charAt(index);
- 현재 index에 있는 문자를 c에 저장
- 7에 있는 문자 d 저장
3. 재귀 호출
String result = calculFn(str, index - 1, seen);
- 이전 문자를 확인하기 위해 함수 자신을 호출 여기서 계속해서 호출만 되고, 결과는 잠시 멈춥니다! 여기까지는 단지 호출만 계속하고, 모두 멈춰 결과 기다리는 상태입니다
- 예: calculFn(str, 6, seen) → calculFn(5) → calculFn(4) … → calculFn(-1)까지 간 다음에야 result 값이 생깁니다.
- index = 7 이므로 7-1=6
calculFn(str, 6, seen) 호출
↓
calculFn("abacabcd", 6) → 'c'
다음 호출로 진행 (index-1 = 5)
↓
calculFn("abacabcd", 5) → 'b'
다음 호출로 진행 (index-1 = 4)
↓
calculFn("abacabcd", 4) → 'a'
다음 호출로 진행 (index-1 = 3)
↓
calculFn("abacabcd", 3) → 'c'
다음 호출로 진행 (index-1 = 2)
↓
calculFn("abacabcd", 2) → 'a'
다음 호출로 진행 (index-1 = 1)
↓
calculFn("abacabcd", 1) → 'b'
다음 호출로 진행 (index-1 = 0)
↓
calculFn("abacabcd", 0) → 'a'
다음 호출로 진행 (index-1 = -1)
↓
calculFn("abacabcd", -1) → base case, return ""
재귀 종료, 빈 문자열 "" 반환
4. 재귀 복귀 시작 (결과 결합)
함수는 자기가 호출한 다른 함수의 결과가 돌아오기 전까지는 return을 못합니다. 그래서 맨 마지막 함수만 먼저 return하고,그 다음부터 하나씩 위로 올라오며 순차적으로 return되는 것처럼 보입니다 이게 바로 재귀 복귀 단계입니다.
📌 seen[c] 검사
if (!seen[c]) { // 아직 c 문자가 등장한 적이 없다면
seen[c] = true; // 이제 이 문자가 등장했으니까 true로 바꿔줌
return c + result; // 현재 문자 c를 앞에 붙여서 반환
}
- seen[c]를 계산하면, 'a' → ASCII 코드 97이므로 seen['a'] = seen[97] 그리고 seen은 모든 값이 false인 boolean 배열
- 따라서 seen[c]는 false이지만 !연사자로 인해 true
- [참고] 아스키코드(ASCII code)에서 문자 'a'부터 'Z'까지의 범위
대문자 A~Z : A(65)~Z(90)
소문자 a~z : a(97)~z(122)
return result;
- seen[c]가 true면 그냥 result만 반환
📌 재귀 복귀
- index = 0, 문자 = 'a'
- result = ""
- seen['a'] = false → true로 바꾸고
- 반환: 'a' + "" = "a"
- index = 1, 문자 = 'b'
- result = "a"
- seen['b'] = false → true로 바꾸고
- 반환: 'b' + "a" = "ba"
- index = 2, 문자 = 'a'
- result = "ba"
- seen['a'] = true → 이미 등장했으므로
- 반환: "ba"
- index = 3, 문자 = 'c'
- result = "ba"
- seen['c'] = false → true로 바꾸고
- 반환: 'c' + "ba" = "cba"
- index = 4, 문자 = 'a'
- result = "cba"
- seen['a'] = true → 이미 등장
- 반환: "cba"
- index = 5, 문자 = 'b'
- result = "cba"
- seen['b'] = true → 이미 등장
- 반환: "cba"
- index = 6, 문자 = 'c'
- result = "cba"
- seen['c'] = true → 이미 등장
- 반환: "cba"
- index = 7, 문자 = 'd'
- result = "cba"
- seen['d'] = false → true로 바꾸고
- 반환: 'd' + "cba" = "dcba"
[ 재귀 호출 & 복귀 흐름 표 ]
4️⃣ 출력
System.out.print(calculFn(str, str.length() - 1, seen));
- 출력값: dcba
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
728x90
반응형
'코딩일기 > 자격증' 카테고리의 다른 글
[정보처리기사] [Java] split() 메서드 | 문자열 분할 | 2024년 2회 정보처리기사 실기 기출문제 (0) | 2025.05.09 |
---|---|
[정보처리기사] [ C ] 구조체와 포인터 | 연결 리스트(Linked List) | 2024년 2회 실기 기출문제 해설 (0) | 2025.05.08 |
[정보처리기사] [Java] 인터페이스 구현 | 짝수와 홀수의 합 구하기 | 2024년 2회 정보처리기사 실기 기출문제 (0) | 2025.04.18 |
[정보처리기사] [ C ] 포인터를 활용한 문자열 복사 | 2024년 2회 정보처리기사 실기 기출문제 (0) | 2025.04.18 |
[정보처리기사] [ C ] switch문 실행 흐름 | 2024년 2회 정보처리기사 실기 기출문제 (0) | 2025.04.11 |