• Home
  • About
    • Ryureka Moment photo

      Ryureka

      Sin Prisa, Sin Pausa

    • About Me
    • Facebook
    • Github
    • Youtube
  • Projects
  • Posts
    • Posts
    • ProblemSolvings
    • Tags
    • Blog
    • TIL
    • Examples
  • ProblemSolving
    • ProblemSolving
    • BOJ
    • Programmers
    • SWEA
    • LeetCode
  • FrontEnd
    • FrontEnd
    • HTML
  • BackEnd
    • BackEnd
    • Server
      • Server
      • Spring
      • NodeJS
    • DataBase
      • DataBase
      • MySQL
      • MongoDB
  • Programming
    • Programming
    • Java
    • Javascript
    • Python
    • CleanCode
  • ComputerScience
    • DataStructure
    • Algorithm

중첩 if문 제거 과정 (feat. [Programmers] Lv2. 마법의 엘리베이터)

09 Jan 2023

Reading time ~6 minutes

이 포스트는 프로그래머스 마법의 엘리베이터 문제를 풀면서 제가 공부했던 내용을 다시 상기시킬 목적으로 작성한 글입니다.
public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number == 5){
			answer += 5; // 5를 (10 - number)로 생각하면 아래 else if문과 중복된 코드
			if(i-1 >= 0 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
		} else if(number > 5) {
			answer += (10 - number);                
			if(i-1 >= 0) { 
				numbers[i-1]++;
			}
		} else {
			answer += number;
		}    
	}

	return answer;
}

가장 짧은 부분인 else 문에 해당하는 부분을 if 문으로 변경하여 조건을 명시한 후 맨 위로 올린다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
		} else if(number == 5){
			answer += 5; // 5를 (10 - number)로 생각하면 아래 else if문과 중복된 코드
			if(i-1 >= 0 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
		} else {
			answer += (10 - number);                
			if(i-1 >= 0) { 
				numbers[i-1]++;
			}
		}    
	}

	return answer;
}

number < 5인 경우 answer += number 말고는 for문 내에 더 실행할 명령이 없으므로 continue를 사용하여 else if문의 첫 번째 else를 제거한다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		} 
		
		if(number == 5){
			answer += 5; // 5를 (10 - number)로 생각하면 아래 else if문과 중복된 코드
			if(i-1 >= 0 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
		} else {
			answer += (10 - number);                
			if(i-1 >= 0) { 
				numbers[i-1]++;
			}
		}    
	}

	return answer;
}

5를 (10 - number)로 고친다

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		} 
		
		if(number == 5){
			answer += (10 - number);
			if(i-1 >= 0 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
		} else {
			answer += (10 - number);                
			if(i-1 >= 0) { 
				numbers[i-1]++;
			}
		}    
	}

	return answer;
}

중복되는 answer += (10 - number) 부분을 남기고 따로 추출한다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		} 
		
		if(number == 5){
			answer += (10 - number);                
		} else {
			answer += (10 - number);                                
		}    
		
		if(number == 5 && i-1 >= 0 && numbers[i-1] >= 5){
			numbers[i-1]++;
		}
		
		if(number > 5 && i-1 >= 0) { 
			numbers[i-1]++;
		}
	}

	return answer;
}

if else 모두 같은 결과이므로 if else문을 삭제한다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(number == 5 && i-1 >= 0 && numbers[i-1] >= 5){
			numbers[i-1]++;
		}
		
		if(number > 5 && i-1 >= 0) { 
			numbers[i-1]++;
		}
	}

	return answer;
}

i-1 >= 0이 중복으로 있으므로 이것을 기준으로 하나의 if문으로 묶어낸다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 >= 0){
			if(number == 5 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
			if(number > 5) { 
				numbers[i-1]++;
			}
		}
	}

	return answer;
}

그 아래 비어있는 else문을 써 넣어본다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 >= 0){
			if(number == 5 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
			if(number > 5) { 
				numbers[i-1]++;
			}
		} else {
		
		}
	}

	return answer;
}

else문에 조건을 넣고 if문에 있는 조건을 else문으로 바꾼다. (보호절 방식으로 !을 붙이는 것이라 생각하면 된다.)

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 < 0){
			
		} else {
			if(number == 5 && numbers[i-1] >= 5){
				numbers[i-1]++;
			}
			if(number > 5) { 
				numbers[i-1]++;
			}
		}
	}

	return answer;
}

if(i-1 < 0)일 때는 for문 내에 더 실행할 명령이 없으므로 continue를 넣고 else를 제거한다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 < 0){
			continue;
		}
		
		if(number == 5 && numbers[i-1] >= 5){
			numbers[i-1]++;
		}
		if(number > 5) { 
			numbers[i-1]++;
		}            
	}

	return answer;
}

if문안에 같은 numbers[i-1]++이 있으므로 중복을 제거해보자. number와 numbers[i-1] 두 개의 조건이 있으므로 이와 관련해서 4가지 조건을 모두 만든다. number < 5인 경우는 맨 위에 continue에서 걸려서 처리되었으므로 생각하지 않는다.

그러면 number와 numbers[i-1]로 만들 수 있는 모든 조건을 아래와 같이 네 개의 식으로 구성할 수 있다. number > 5인 경우 numbers[i-1] 값에 관계없이 numbers[i-1]++을 실행하면 된다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
		answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 < 0){
			continue;
		}
		
		if(number == 5 && numbers[i-1] >= 5){
			numbers[i-1]++;
		} else if(number == 5 && numbers[i-1] < 5){

		} else if(number > 5 && numbers[i-1] >= 5){
			numbers[i-1]++;
		} else if(number > 5 && numbers[i-1] < 5) { // else와 동일하지만 명시적으로 표현했음.
			numbers[i-1]++;
		}	            
	}

	return answer;
}

여기서 비어있는 else if(number == 5 && numbers[i-1] < 5)를 맨위의 if문으로 올린다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 < 0){
			continue;
		}
		
		if(number == 5 && numbers[i-1] < 5){

		} else if(number == 5 && numbers[i-1] >= 5){
			numbers[i-1]++;
		} else if(number > 5 && numbers[i-1] >= 5){
			numbers[i-1]++;
		} else if(number > 5 && numbers[i-1] < 5) { // else와 동일하지만 명시적으로 표현했음.
			numbers[i-1]++;
		}	            
	}

	return answer;
}

세 개의 else if 안에 실행할 명령이 numbers[i-1]++으로 공통이고 나머지 모든 경우를 커버하므로 하나의 else로 묶는다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 < 0){
			continue;
		}
		
		if(number == 5 && numbers[i-1] < 5){

		} else {
			numbers[i-1]++;
		}	            
	}

	return answer;
}

if문에 continue를 넣고 밑에 else를 제거한다.

public int solveWithGreedy(int storey){        
	int answer = 0;
	int numbersLength = getLength(storey);
	int[] numbers = getSplitNumbers(storey);
	
	for(int i = numbersLength; i >= 0; i--) {
		int number = numbers[i];
		if(number < 5){
			answer += number;
			continue;
		}             

		answer += (10 - number);                
		
		if(i-1 < 0){
			continue;
		}
		
		if(number == 5 && numbers[i-1] < 5){
			continue;
		}

		numbers[i-1]++;	            
	}

	return answer;
}

이렇게 중첩된 if문을 제거해보았다. 들여쓰기도 적고 가독성 면에서 더 깔끔해진 코드로 바뀌었다.



CleanCode Share