https://school.programmers.co.kr/learn/courses/30/lessons/340210
코딩테스트 연습 > PCCP 기출문제 > [PCCP 기출문제] 4번 / 수식 복원하기
문제 분석
난이도: LEVEL3
문제유형: 구현 + 다양한 진법 변환
정답 코드
import java.util.*;
class Solution {
static int target = 2; // 후보 진법: target ~ 9
static char [] blackList = {' ', '+', '-', '=', 'X'};
static ArrayList<String> A = new ArrayList<>(); // 정상 수식
static ArrayList<String> Q = new ArrayList<>(); // 풀어야 하는 수식
static ArrayList<ArrayList<String>> A_List = new ArrayList();
static ArrayList<ArrayList<String>> Q_List = new ArrayList();
static boolean [] possible = new boolean [10]; // 가능한 진법
public String[] solution(String[] expressions) {
function(expressions);
Arrays.fill(possible, true);
for(String tar : A){
function2(tar, "A");
}
for(String tar : Q){
function2(tar, "Q");
}
function3();
return function4();
}
public static String [] function4(){
for(ArrayList<String> list : Q_List){
String first = list.get(0);
String second = list.get(2);
String result = "";
boolean flag = false;
for(int i = target; i <= 9; i++){
if(!possible[i]) continue;
int cnt = 0;
int first_int = 0;
int second_int = 0;
for(int j = first.length() - 1; j >=0; j--){
first_int += (int) Math.pow(i, cnt) * (first.charAt(j) - '0');
cnt++;
}
cnt = 0;
for(int j = second.length() - 1; j >=0; j--){
second_int += (int) Math.pow(i, cnt) * (second.charAt(j) - '0');
cnt++;
}
if(list.get(1).equals("+")){
int temp = first_int + second_int;
StringBuilder sb = new StringBuilder();
while(temp >= i){
sb.append(temp % i);
temp /= i;
}
sb.append(temp);
sb.reverse();
String temp2 = sb.toString();
if(result.equals("")){
result = temp2;
}
else{
if(!result.equals(temp2)){
flag = true;
}
}
}
else{
int temp = first_int - second_int;
StringBuilder sb = new StringBuilder();
while(temp >= i){
sb.append(temp % i);
temp /= i;
}
sb.append(temp);
sb.reverse();
String temp2 = sb.toString();
if(result.equals("")){
result = temp2;
}
else{
if(!result.equals(temp2)){
flag = true;
}
}
}
}
if(!flag){ // result 삽입
list.set(4, result);
}
else{
list.set(4, "?");
}
}
String [] answer = new String [Q_List.size()];
for(int i = 0; i < Q_List.size(); i++){
StringBuilder sb = new StringBuilder();
ArrayList<String> list = Q_List.get(i);
for(int j = 0; j < 5; j++){
sb.append(list.get(j));
if(j != 4){
sb.append(" ");
}
}
answer[i] = sb.toString();
}
return answer;
}
public static void function3(){ // 정상 수식에서 불가능한 진법 찾기
for(ArrayList<String> list : A_List){
String first = list.get(0);
String second = list.get(2);
String result = list.get(4);
for(int i = target; i <= 9; i++){
if(!possible[i]) continue;
int cnt = 0;
int first_int = 0;
int second_int = 0;
int result_int = 0;
for(int j = first.length() - 1; j >=0; j--){
first_int += (int) Math.pow(i, cnt) * (first.charAt(j) - '0');
cnt++;
}
cnt = 0;
for(int j = second.length() - 1; j >=0; j--){
second_int += (int) Math.pow(i, cnt) * (second.charAt(j) - '0');
cnt++;
}
cnt = 0;
for(int j = result.length() - 1; j >=0; j--){
result_int += (int) Math.pow(i, cnt) * (result.charAt(j) - '0');
cnt++;
}
if(list.get(1).equals("+")){
if(first_int + second_int != result_int){
possible[i] = false;
}
}
else{
if(first_int - second_int != result_int){
possible[i] = false;
}
}
}
}
}
public static void function2(String tar, String check){ // 분리하기
String [] split = tar.split(" ");
ArrayList<String> temp = new ArrayList<>();
for(String cur : split){
temp.add(cur);
}
if(check.equals("A")){
A_List.add(temp);
}
else Q_List.add(temp);
}
public static void function(String [] expressions){ // 가장 높은 숫자 찾기
for(String tar : expressions){
boolean q = false;
for(int i = 0; i < tar.length(); i++){
char cur = tar.charAt(i);
boolean flag = false;
for(char check : blackList){
if(check == cur){
flag = true;
if(check == 'X') q = true;
break;
}
}
if(flag) continue;
int temp = cur - '0' + 1;
if(target < temp) target = temp;
}
if(q){
Q.add(tar);
}
else{
A.add(tar);
}
}
}
}
각 과정을 더 간결하게 할 수 있을듯한데 리팩토링하기 너무 무섭네요 ㅋㅋ
2시간 정도 소요하는 빡 구현 문제였습니다
function()
function()의 기능은 수식들에서 가장 높은 숫자를 찾는 함수였습니다.
진법 후보가 2~9 사이인데 가장 높은 숫자를 찾으면 진법 후보를 쉽게 줄일 수 있습니다.
ex) 3진법
3진법에서 나올 수 있는 가장 큰 숫자는 2
가장 큰 숫자가 7이라면
진법 후보는 8 ~ 9
가장 높은 숫자만 찾는 역할을 한건 아니고 추가적으로 "X"의 유무로 정상 수식인지 풀어야 하는 수식인지 구별하고
저장하였습니다.
function2()
split(" ") API를 활용하여 문자열에서 숫자 기호로 풀고 정상 수식, 풀어야 하는 수식 이중 리스트인 A_List, Q_List에 각각 추가하였습니다.
function3()
정상 수식을 기반으로 해당 진법으로 계산 결과가 결과와 다르면 후보 진법에서 거르는 계산을 진행
function4()
풀어야 하는 수식들을 가져와서 가능한 진법으로 계산을 하고 해당 수식의 결과가 2개 이상으로 나오면 결과를 ? 처리
아니라면 숫자를 집어넣었습니다.
이때 중요한 점은 계산은 10진법으로 바꿔서 진행하지만 결과 비교는 다시 해당 진법으로 바꾸는 것이었습니다.
바꾼 수식을 String [] 배열로 return 하고 soution 메서드에서 반환하면 모든 과정이 끝납니다.
'Algorithm > Programmers Java' 카테고리의 다른 글
[JAVA] 프로그래머스 LEVEL3 에어컨 (0) | 2024.09.22 |
---|---|
[JAVA] 프로그래머스 LEVEL3 등산코스 정하기 (1) | 2024.09.22 |
[JAVA] 프로그래머스 [PCCP 기출문제] 3번 / 충돌위험 찾기 (1) | 2024.09.13 |
[JAVA] 프로그래머스 [PCCP 기출문제] 2번 / 퍼즐 게임 챌린지 (0) | 2024.09.13 |
[JAVA] 프로그래머스 level2 메뉴 리뉴얼 (0) | 2024.08.05 |