제어문(Control Flow Statements) - 반복문
학습 목표
반복문 기초 / 실습
- 반복문을 활용하여 단순한 기능을 반복하여 수행할 수 있다.
- 반복문과 문자열, 숫자를 이용해 반복적으로 코드를 실행시킬 수 있다.
- 반복문을 다양하게 응용하여 활용할 수 있다.
- for문과 while문의 공통점과 차이점을 이해할 수 있다.
- 반복문에 조건문을 적용하여 특정 조건에서만 코드가 실행되도록 할 수 있다.
- 이중 for문이 무엇인지 이해하고 활용할 수 있다.
반복문
반복문은 코드들이 반복적으로 실행되도록 할 때 사용되며, 반복문의 종류로는 for문, while문, do-while문이 있습니다. for문과 while문은 서로 변환이 가능하기 때문에 반복문을 작성할 때 어느 쪽을 선택해도 좋지만, for문은 반복 횟수를 알고 있을 때 주로 사용하고, while문은 조건에 따라 반복할 때 주로 사용합니다.
for문
for문은 조건식이 참인 동안 주어진 횟수만큼 실행문을 반복적으로 수행합니다.
public class Main {
public static void main(String[] args) {
int sum = 0;
// for (초기화; 조건식; 증감식)
for(int num = 0; num < 10; num++) {
sum += num;
}
System.out.println(sum); // 1~9의 합인 45가 출력됩니다.
}
}
여기서 num은 number(숫자)의 줄임말로, 임의로 지정한 변수명입니다. 여러분이 원하는 변수명을 사용해도 됩니다. 다만 반복문에는 i라는 변수명을 많이 사용합니다. i는 iterator(반복계수)를 의미합니다.
만약 반복문이 없다면, 우리는 sum = sum + (숫자); 와 같은 구문을 10번 작성해주어야 할 것입니다. 하지만 for문을 사용하면 이와 같이 코드를 획기적으로 줄일 수 있습니다. 그럼 for문의 구조를 하나씩 살펴보겠습니다.
- 초기화는 for문이 시작할 때 최초 한 번만 수행되며, 사용할 변수의 초깃값을 정합니다.
- 조건식은 계속 반복할지 여부를 결정하는 조건입니다. 조건식 안의 값이 true라면 실행문을 실행시키고, false라면 더 이상 블록을 실행하지 않고 끝납니다.
- 증감식은 반복 횟수를 결정하는 규칙입니다. 변수에 값을 더하거나 곱하는 등 수행 방식을 지정합니다. ++ 은 반복문에서 자주 쓰는 증감연산자로, 피연산자의 값을 1 증가시킵니다.
위 코드가 실행되는 과정을 하나씩 살펴보겠습니다.
- num이라는 변수를 선언하고, 초깃값으로 0을 대입합니다.
- num는 현재 10보다 작으므로(num < 10), 실행 블록 안의 코드가 최초로 수행됩니다.
- 실행 블록을 빠져나오면 num이 1 증가합니다(i++).
- num은 현재 1입니다. 여전히 10보다 작으므로, 실행 블록 안의 코드가 두 번째로 수행됩니다.
- num이 9일 때까지 반복됩니다.
- num이 10이 되면 10보다 작다는 조건을 만족하지 못하므로, for문이 종료됩니다.
- 질문) 실행 블록 안의 코드는 총 몇 번 수행될까요?
for문을 좀 더 쉽게 설명하자면, 조건식을 충족하는 동안 초기화식부터 시작해서 증감식의 규칙을 따라서 실행합니다. 조건이 충족하지 않으면, 실행문을 실행하지 않고 끝나게 됩니다. 따라서 초기화식이 필요 없을 경우에는 초기화식을 생략할 수 있고, 다음 예시와 같이 초기화식이나 증감식도 둘 이상이 될 수 있습니다.
for(int i=0, j=100; i<=50 && j>=50; i++, j--) {
실행문;
실행문;
}
향상된 for문 (Enhanced for 문)
배열과 이후 학습하게 되는 컬렉션 객체를 좀 더 쉽게 처리할 목적으로, 자바에서는 향상된 for문을 제공합니다. 향상된 for문은 반복실행을 하기 위해 카운터 변수와 증감식을 사용하지 않습니다. 배열 및 컬렉션 항목의 개수만큼 반복하고 자동적으로 for문을 빠져나갑니다. 참고로 배열에 대한 좀 더 자세한 내용은 이어지는 챕터에서 학습할 예정이니, 지금은 향상된 for문이 대략적으로 어떻게 사용되는지에 대한 흐름을 중심으로 한번 살펴보도록 합니다. 다음 예시를 통해 향상된 for문을 조금 더 살펴보겠습니다.
public class EnhancedForLoop {
public static void main(String[] args) throws Exception {
String[] names = {"kimcoding", "javalee", "choihojea"};
for(String name : names) {
System.out.println(name + "님은 자바를 공부중 입니다.");
}
}
}
/*
kimcoding님은 자바를 공부중 입니다.
javalee님은 자바를 공부중 입니다.
choihojea님은 자바를 공부중 입니다.
*/
위와 같이 for문의 괄호( ()) 안에는 배열에서 꺼낸 항목을 저장할 변수 선언, 콜론( : ), 그리고 사용할 배열이 작성됩니다. 향상된 for문을 처음 실행 할 때, names 배열에서 가져올 첫 번째 값이 존재하는지 확인하고, 값이 존재하면 해당값을 변수인 name에 저장합니다. 그리고 그 안의 실행문을 실행합니다. 블록 내부의 실행문이 모두 실행되면 다시 names 배열에서 가져올 값이 있는지 확인하고 만약 가져올 다음 항목이 없다면 자동적으로 for문이 종료됩니다.
while문
for문이 정해진 횟수만큼 반복한다면, while문은 조건식이 true일 경우에 계속해서 반복합니다.
for문과 while문은 초기화, 증감식의 위치만 다를 뿐 상호 대체가 가능합니다.
(초기화);
while(조건식) {
실행문; //조건식이 참인 동안 실행
증감식;
}
초기화와 증감식은 필요가 없다면 생략할 수 있습니다.
while문이 실행되는 과정을 하나씩 살펴보겠습니다.
int num = 0, sum = 0;
while(num <= 10) {
sum += num; //sum = sum + num과 똑같은 식입니다. 복합 대입 연산자 "+="를 사용한 표현입니다.
num++;
}
System.out.println(sum);
- num과 sum이라는 정수 타입의 변수를 선언하고 초기값으로 0을 대입합니다.
- num은 현재 10보다 작으므로 블록 안의 코드가 수행됩니다.
- sum이 현재의 num만큼 증가하고 num이 1 증가합니다
- num은 현재 1입니다. 여전히 10보다 작으므로, 실행 블록 안의 코드가 두 번째로 수행됩니다.
- num이 10인 경우까지 반복됩니다.
- num은 현재 11입니다. 조건식이 거짓이므로 while문이 종료됩니다.
- 질문) System.out.println(sum);으로 출력되는 값은 몇일까요?
이때 조건식에는 boolean 변수나 true / false 값을 산출하는 어떠한 연산식이든 올 수 있습니다. 하지만 만약 조건식에 true를 사용하면 while(true) { ... }가 되어서 무한 루프를 돌게 됩니다. 무한 루프는 무한히 반복하여 실행하기 때문에 언젠가는 while문을 빠져나가기 위한 탈출 코드가 필요합니다. 다음 예시를 보겠습니다.
public class Main {
public static void main(String[] args) {
boolean run = true;
int num = 1;
while(run){ // while(true) 조건문
num++; //실행문
System.out.println(num); //실행문
if(num == 22) { //조건문, num이 22가 되면 탈출! 얏호!
run = false;
}
}
}
}
위 코드는 num이 22가 되었을 때 탈출 하는 탈출 코드를 작성하였지만, while문을 빠져나가기 위한 또 다른 방법으로는 break문을 이용하는 방법도 있습니다. break문에 대해서는 이후에 설명하도록 하겠습니다.
do-while문
do-while문은 조건식에 의해 반복 실행한다는 점에서는 while문과 동일합니다. while문은 시작할 때부터 조건식을 검사하여 블록 내부를 실행할지 결정하지만, 경우에 따라서는 블록 내부의 실행문을 우선 실행시키고 실행 결과에 따라서 반복 실행을 계속할지 결정하는 경우도 있습니다.
다음은 do-while문의 기본 형식입니다.
do {
(1)실행문 //처음 한 번은 무조건 실행
} while((2)조건식);
do-while문이 처음 실행될 때 (1) 실행문을 먼저 실행합니다. (1) 실행문이 모두 실행되면 (2) 조건식을 평가합니다. 그리고 그 결과가 true이면 (1) 실행문 → (2) 조건식으로 반복 실행을 하고, false이면 do-while문을 종료합니다.
다음 예제 코드를 보겠습니다.
import java.util.Scanner;
public class Main {
public static void main(String args[]){
int input = 0, randomNum = 0;
randomNum = (int)(Math.random() * 10) + 1; // 1 ~ 10 임의의 수를 생성
Scanner scanner = new Scanner(System.in);
do{
System.out.println("1과 10 사이의 정수를 입력하세요");
input = scanner.nextInt();
if(input > randomNum) {
System.out.println("더 작은 정수를 입력하세요");
} else if (input < randomNum) {
System.out.println("더 큰 정수를 입력하세요");
}
} while(input != randomNum);
System.out.println(randomNum +" 정답입니다!");
}
}
1~10 사이의 정수를 변수 randomNum에 저장하고 이 값을 맞출 때까지 반복하는 do-while문입니다.
break문과 continue문
break문
break문은 반복문인 for문, while문, do-while문을 실행 중지할 때 사용됩니다. 또한 이전에 학습한 switch문에서도 break문을 사용하여 switch문을 종료합니다.
break문은 대개 if문과 같이 사용되며, if문의 조건식에 따라 for / while문을 종료할 때 사용합니다.
만약, 반복문이 중첩되어 있을 경우 break문은 가장 가까운 반복문만 종료하고, 바깥쪽 반복문에는 영향을 끼치지 않습니다. 아래 예제를 통해 이해해 봅시다.
public class Main {
public static void main(String[] args) {
Outer : for (int i = 3; i < 10; i++) {
for (int j = 5; j > 0; j--) {
System.out.println("i " + i + " j "+ j);
if (i == 5) {
break Outer;
}
}
}
}
}
/*
i 3 j 5
i 3 j 4
i 3 j 3
i 3 j 2
i 3 j 1
i 4 j 5
i 4 j 4
i 4 j 3
i 4 j 2
i 4 j 1
i 5 j 5
*/
위 코드에서 바깥 for문은 3부터 9까지 반복하고, 중첩된 안쪽 for문은 5부터 1까지 반복합니다. 바깥 for문에서 변수 i의 값이 5가 되면 바깥 for문까지 빠져나올 수 있도록 해당 for문에 Outer라는 라벨을 붙이고, 이를 break문에 사용했습니다. 이런 식으로 레이블문을 쓰면, 중첩된 for문 안에서도 바깥쪽 for문까지 완벽하게 빠져나올 수 있습니다.
continue문
continue문은 반복문인 for문, while문, do-while문에서만 사용되는데, 블록 내부에서 continue문이 실행되면 for문의 증감문 혹은 while, do-while문의 조건식으로 이동하여 작동합니다. continue문과 break문의 차이점은 반복문 종료 여부입니다. continue문은 반복문을 종료하지 않고 다음 차례로 넘어가 계속 반복을 수행합니다. break문과 마찬가지로 continue문도 보통 if문과 함께 사용하는데, if문의 조건을 만족하는 경우 continue문을 실행하여 그 이후의 코드를 실행하지 않고 다음 반복으로 넘어갑니다.
아래 예제는 1 ~10까지의 수 중에서 홀수만 출력하는 코드입니다. if문을 사용하여 짝수인 경우는 다시 for문의 증감문으로 이동하여 다음 반복을 실행하고, 홀수만 출력합니다.
public class Main {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) { //나머지가 0일 경우는
continue; //다음 반복으로 넘어간다.
}
System.out.println(i); //홀수만 출력
}
}
}
/*
1,3,5,7,9
*/
1. sum
문제
수를 입력받아 0부터 해당 수까지의 합을 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수 (num >= 0)
출력
- int 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
입출력 예시
int output = sumTo(3);
System.out.println(output); // --> 6
public class Solution {
public int sumTo(int num) {
int result = 0;
//TODO :
}
}
정답
package com.choongang;
public class A_Sum {
public int sumTo(int num) {
// TODO:
int result = 0;
for (int i = 0; i <= num; i++) {
result += i;
}
return result;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class A_SumTest {
A_Sum test = new A_Sum();
@Test
@DisplayName("0을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void sumTo() {
assertThat(test.sumTo(0)).isEqualTo(0);
}
@Test
@DisplayName("4을(를) 입력받은 경우, 10을(를) 리턴해야 합니다")
void sumTo2() {
assertThat(test.sumTo(4)).isEqualTo(10);
}
@Test
@DisplayName("77을(를) 입력받은 경우, 3003을(를) 리턴해야 합니다")
void sumTo3() {
assertThat(test.sumTo(77)).isEqualTo(3003);
}
}
2. isOdd
문제
수를 입력받아 홀수인지 여부를 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수
출력
- boolean 타입을 리턴해야 합니다.
주의 사항
- 반복문(while)문을 사용해야 합니다.
- for문 사용은 금지됩니다.
- 나눗셈(/), 나머지(%) 연산자 사용은 금지됩니다.
- 0은 짝수로 간주합니다.
입출력 예시
boolean output = isOdd(17);
System.out.println(output); // --> true
output = isOdd(-8);
System.out.println(output); // --> false
public class Solution {
public boolean isOdd(int num) {
//조건문을 사용하여 짝수인 경우 return false를,
//홀수인 경우 return true;를 작성해야 합니다.
//TODO :
}
}
정답
package com.choongang;
public class B_IsOdd {
public boolean isOdd(int num) {
// TODO:
boolean output = false;
if (num < 0) {
num *= -1;
}
while (num >= 2) {
num -= 2;
}
output = (num == 1) ? true : false;
return output;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.InstanceOfAssertFactories.list;
class B_IsOddTest {
B_IsOdd test = new B_IsOdd();
@Test
@DisplayName("77을(를) 입력받은 경우, true를 리턴해야 합니다")
void isOdd() {
assertThat(test.isOdd(77)).isTrue();
}
@Test
@DisplayName("100을(를) 입력받은 경우, false를 리턴해야 합니다")
void isOdd2() {
assertThat(test.isOdd(100)).isFalse();
}
@Test
@DisplayName("0을(를) 입력받은 경우, false를 리턴해야 합니다")
void isOdd3() {
assertThat(test.isOdd(0)).isFalse();
}
@Test
@DisplayName("-17을(를) 입력받은 경우, true를 리턴해야 합니다")
void isOdd4() {
assertThat(test.isOdd(-17)).isTrue();
}
@Test
@DisplayName("-1000을(를) 입력받은 경우, false를 리턴해야 합니다")
void isOdd5() {
assertThat(test.isOdd(-1000)).isFalse();
}
}
3. factorial
문제
수를 입력받아 n-factorial(n!) 값을 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수 (num >= 0)
출력
- int 타입을 리턴해야 합니다.
- 1 * 2 * ... * num
주의 사항
- 반복문(for)문을 사용해야 합니다.
- factorial(0)은 1로 정의됩니다.
- 음수 입력은 들어오지 않습니다.
입출력 예시
int output = factorial(5);
System.out.println(output); // --> 120
힌트
factorial(n)은 자연수 1부터 n까지의 곱을 계산하는 함수입니다.
factorial(1) = 1
factorial(2) = 1 * 2 = 2
factorial(3) = 1 * 2 * 3 = 6
factorial(4) = 1 * 2 * 3 * 4 = 24
public class Solution {
public int factorial(int num) {
int result = 1;
//TODO :
}
}
정답
package com.choongang;
public class C_Factorial {
public int factorial(int num) {
// TODO:
int result = 1;
for (int i = 1; i <= num; i++) {
result *= i;
}
return result;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class C_FactorialTest {
C_Factorial test = new C_Factorial();
@Test
@DisplayName("0을(를) 입력받은 경우, 1을(를) 리턴해야 합니다")
void factorial() {
assertThat(test.factorial(0)).isEqualTo(1);
}
@Test
@DisplayName("4을(를) 입력받은 경우, 24을(를) 리턴해야 합니다")
void factorial2() {
assertThat(test.factorial(4)).isEqualTo(24);
}
@Test
@DisplayName("10을(를) 입력받은 경우, 3628800을(를) 리턴해야 합니다")
void factorial3() {
assertThat(test.factorial(10)).isEqualTo(3628800);
}
}
4. repeatString
문제
문자열과 수를 입력받아 반복된 문자열을 리턴해야 합니다.
입력
인자 1 : str
- string 타입의 문자열
인자 2 : num
- int 타입의 정수 (num >= 0)
출력
- string 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- 0을 입력받은 경우, 빈 문자열을 리턴해야 합니다.
입출력 예시
String output = repeatString("code", 3);
System.out.println(output); // --> "codecodecode"
힌트
빈 문자열을 확인하는 방법은 str.isEmpty()를 사용하여 쉽게 확인이 가능합니다.
public class Solution {
public String repeatString(String str, int num) {
String result = "";
// TODO:
}
}
정답
package com.choongang;
public class D_RepeatString {
public String repeatString(String str, int num) {
// TODO:
String result = "";
if (str.isEmpty() || num == 0) {
result = "";
}
for (int i = 0; i < num; i++) {
result += str;
}
return result;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.as;
import static org.assertj.core.api.Assertions.assertThat;
class D_RepeatStringTest {
D_RepeatString test = new D_RepeatString();
@Test
@DisplayName("차례대로 \"what\", 3을(를) 입력받은 경우, \"whatwhatwhat\"을(를) 리턴해야 합니다")
void repeatString() {
assertThat(test.repeatString("what", 3)).isEqualTo("whatwhatwhat");
}
@Test
@DisplayName("차례대로 \"what\", 0을(를) 입력받은 경우, 빈 문자열을(를) 리턴해야 합니다")
void repeatString2() {
assertThat(test.repeatString("what", 0)).isEqualTo("");
}
@Test
@DisplayName("차례대로 \"\", 10000을(를) 입력받은 경우, 빈 문자열을(를) 리턴해야 합니다")
void repeatString3() {
assertThat(test.repeatString("", 10000)).isEqualTo("");
}
}
5. makeDigits
문제
수(num)를 입력받아 1부터 num까지의 정수로 구성된 문자열을 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수 (num >= 1)
출력
- string 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- 숫자(number string) 사이의 구분은 없습니다. ('1234567')
입출력 예시
String output = makeDigits(5);
System.out.println(output); // --> "12345"
output = makeDigits(7);
System.out.println(output); // --> "1234567"
public class Solution {
public String makeDigits(int num) {
String result = "";
// TODO:
}
}
정답
package com.choongang;
public class E_MakeDigits {
public String makeDigits(int num) {
// TODO:
String output = "";
for (int i = 1; i <= num; i++) {
output += i;
}
return output;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class E_MakeDigitsTest {
E_MakeDigits test = new E_MakeDigits();
@Test
@DisplayName("1을(를) 입력받은 경우, \"1\"을(를) 리턴해야 합니다")
void makeDigits() {
assertThat(test.makeDigits(1)).isEqualTo("1");
}
@Test
@DisplayName("5을(를) 입력받은 경우, \"12345\"을(를) 리턴해야 합니다")
void makeDigits2() {
assertThat(test.makeDigits(5)).isEqualTo("12345");
}
@Test
@DisplayName("13을(를) 입력받은 경우, \"12345678910111213\"을(를) 리턴해야 합니다")
void makeDigits3() {
assertThat(test.makeDigits(13)).isEqualTo("12345678910111213");
}
}
6. makeDigits2
문제
수(num)를 입력받아 1부터 num까지의 정수로 구성된 문자열을 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수 (num >= 1)
출력
- string 타입을 리턴해야 합니다.
주의 사항
- 반복문(while)문을 사용해야 합니다.
- for문 사용은 금지됩니다.
- 숫자(number string) 사이를 '-'로 구분합니다. ('1-2-3-4-5')
입출력 예시
String output = makeDigits2(5);
System.out.println(output); // --> "1-2-3-4-5"
output = makeDigits2(7);
System.out.println(output); // --> "1-2-3-4-5-6-7"
public class Solution {
public String makeDigits2(int num) {
// TODO:
}
}
정답
package com.choongang;
public class F_MakeDigits2 {
public String makeDigits2(int num) {
// TODO:
// num이 3이라면 "1-2-3"
String str = "";
int index = 1;
while (index <= num) {
if (index == num) {
str += index;
} else {
str += index + "-";
}
index++;
}
// str = str.substring(0, str.length() - 1);
return str;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class F_MakeDigits2Test {
F_MakeDigits2 test = new F_MakeDigits2();
@Test
@DisplayName("1을(를) 입력받은 경우, \"1\"을(를) 리턴해야 합니다")
void makeDigits2() {
assertThat(test.makeDigits2(1)).isEqualTo("1");
}
@Test
@DisplayName("5을(를) 입력받은 경우, \"1-2-3-4-5\"을(를) 리턴해야 합니다")
void makeDigits22() {
assertThat(test.makeDigits2(5)).isEqualTo("1-2-3-4-5");
}
@Test
@DisplayName("13을(를) 입력받은 경우, \"1-2-3-4-5-6-7-8-9-10-11-12-13\"을(를) 리턴해야 합니다")
void makeDigits23() {
assertThat(test.makeDigits2(13)).isEqualTo("1-2-3-4-5-6-7-8-9-10-11-12-13");
}
}
7. makeOddDigits
문제
수(num)를 입력받아 1을 포함하여 num개의 홀수로 구성된 문자열을 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수 (num >= 1)
출력
- string 타입을 리턴해야 합니다.
주의 사항
- 반복문(while)문을 사용해야 합니다.
- 숫자(number string) 사이의 구분은 없습니다. ('13579')
입출력 예시
String output = makeOddDigits(3);
System.out.println(output); // --> "135"
output = makeOddDigits(5);
System.out.println(output); // --> "13579"
public class Solution {
public String makeOddDigits(int num) {
// TODO:
}
}
정답
package com.choongang;
public class G_MakeOddDigits {
public String makeOddDigits(int num) {
// TODO:
String str = "";
// 3 -> "123" 이 아니라 "135"
// 1 -> 1, 2 -> 3, 3 -> 5, 4 -> 7, 5 -> 9
int count = 0;
int currentNum = 1;
while (count < num) {
str = str + currentNum;
count++;
currentNum += 2;
}
return str;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class G_MakeOddDigitsTest {
G_MakeOddDigits test = new G_MakeOddDigits();
@Test
@DisplayName("1을(를) 입력받은 경우, \"1\"을(를) 리턴해야 합니다")
void makeOddDigits() {
assertThat(test.makeOddDigits(1)).isEqualTo("1");
}
@Test
@DisplayName("5을(를) 입력받은 경우, \"13579\"을(를) 리턴해야 합니다")
void makeOddDigits2() {
assertThat(test.makeOddDigits(5)).isEqualTo("13579");
}
@Test
@DisplayName("7을(를) 입력받은 경우, \"135791113\"을(를) 리턴해야 합니다")
void makeOddDigits3() {
assertThat(test.makeOddDigits(7)).isEqualTo("135791113");
}
@Test
@DisplayName("25을(를) 입력받은 경우, \"135791113151719212325272931333537394143454749\"을(를) 리턴해야 합니다")
void makeOddDigits4() {
assertThat(test.makeOddDigits(25)).isEqualTo("135791113151719212325272931333537394143454749");
}
}
8. makeMultiplesOfDigit
문제
수를 입력받아 1부터 해당 수까지의 수 중에서 3의 배수로만 구성된 문자열을 리턴해야 합니다.
입력
인자 1 : num
- int 타입의 정수 (num >= 0) 이상의 정수)
출력
- string 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- 숫자(number string) 사이의 구분은 없습니다. ('3691215')
- 3의 배수가 없을 경우, 빈 문자열을 리턴해야 합니다.
입출력 예시
String output = makeMultiplesOfDigit(7);
System.out.println(output); // --> "36"
output = makeMultiplesOfDigit(19);
System.out.println(output); // --> "369121518"
output = makeMultiplesOfDigit(2);
System.out.println(output); // --> ""
public class Solution {
public String makeMultiplesOfDigit(int num) {
// TODO:
}
}
정답
package com.choongang;
public class H_MakeMultiplesOfDigit {
public String makeMultiplesOfDigit(int num) {
// TODO:
String str = "";
for (int i = 1; i <= num; i++) {
if (i % 3 == 0) {
str += i;
}
}
return str;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class H_MakeMultiplesOfDigitTest {
H_MakeMultiplesOfDigit test = new H_MakeMultiplesOfDigit();
@Test
@DisplayName("1을(를) 입력받은 경우, 빈 문자열을 리턴해야 합니다")
void makeMultiplesOfDigit() {
assertThat(test.makeMultiplesOfDigit(1)).isEqualTo("");
}
@Test
@DisplayName("3을(를) 입력받은 경우, \"3\"을(를) 리턴해야 합니다")
void makeMultiplesOfDigit2() {
assertThat(test.makeMultiplesOfDigit(3)).isEqualTo("3");
}
@Test
@DisplayName("9을(를) 입력받은 경우, \"369\"을(를) 리턴해야 합니다")
void makeMultiplesOfDigit3() {
assertThat(test.makeMultiplesOfDigit(9)).isEqualTo("369");
}
@Test
@DisplayName("25을(를) 입력받은 경우, \"3691215182124\"을(를) 리턴해야 합니다")
void makeMultiplesOfDigit4() {
assertThat(test.makeMultiplesOfDigit(25)).isEqualTo("3691215182124");
}
@Test
@DisplayName("55을(를) 입력받은 경우, \"369121518212427303336394245485154\"을(를) 리턴해야 합니다")
void makeMultiplesOfDigit5() {
assertThat(test.makeMultiplesOfDigit(55)).isEqualTo("369121518212427303336394245485154");
}
}
makeMultiplesOfDigit2
문제
두 개의 수를 입력받아 두 수를 포함해 두 수 사이의 수 중 2의 배수의 개수를 리턴해야 합니다.
입력
인자 1 : num1
- int 타입의 정수 (num1 >= 0)
인자 2 : num2
- int 타입의 정수 (num2 >= 0)
출력
- int 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- num1이 num2보다 작지 않을 수도 있습니다.
- 0은 2의 배수가 아니라고 가정합니다.
입출력 예시
int output = makeMultiplesOfDigit2(8, 12);
System.out.println(output); // --> 3
output = makeMultiplesOfDigit2(12, 8);
System.out.println(output); // --> 3
output = makeMultiplesOfDigit2(1, 3);
System.out.println(output); // --> 1
public class Solution {
public int makeMultiplesOfDigit2(int num1, int num2) {
//TODO:
}
}
정답
package com.choongang;
public class I_MakeMultiplesOfDigit2 {
public int makeMultiplesOfDigit2(int num1, int num2) {
// TODO:
// num1 = 8, num2 = 12일때
// num1 = 12, num2 = 8일때
int count = 0;
int start;
int end;
if (num1 < num2) {
start = num1;
end = num2;
} else {
start = num2;
end = num1;
}
for (int i = start; i <= end; i++) {
if (i % 2 == 0 && i != 0) {
count++;
}
}
return count;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class I_MakeMultiplesOfDigit2Test {
I_MakeMultiplesOfDigit2 test = new I_MakeMultiplesOfDigit2();
@Test
@DisplayName("차례대로 0, 0을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void makeMultiplesOfDigit2() {
assertThat(test.makeMultiplesOfDigit2(0, 0)).isEqualTo(0);
}
@Test
@DisplayName("차례대로 0, 1을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void makeMultiplesOfDigit22() {
assertThat(test.makeMultiplesOfDigit2(0, 1)).isEqualTo(0);
}
@Test
@DisplayName("차례대로 1, 0을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void makeMultiplesOfDigit23() {
assertThat(test.makeMultiplesOfDigit2(1, 0)).isEqualTo(0);
}
@Test
@DisplayName("차례대로 9, 3을(를) 입력받은 경우, 3을(를) 리턴해야 합니다")
void makeMultiplesOfDigit24() {
assertThat(test.makeMultiplesOfDigit2(9, 3)).isEqualTo(3);
}
@Test
@DisplayName("차례대로 8, 8을(를) 입력받은 경우, 1을(를) 리턴해야 합니다")
void makeMultiplesOfDigit25() {
assertThat(test.makeMultiplesOfDigit2(8, 8)).isEqualTo(1);
}
@Test
@DisplayName("차례대로 12, 0을(를) 입력받은 경우, 6을(를) 리턴해야 합니다")
void makeMultiplesOfDigit26() {
assertThat(test.makeMultiplesOfDigit2(12, 0)).isEqualTo(6);
}
}
10. findTheBug
문제
문자열을 입력받아 버그('#')의 인덱스를 리턴해야 합니다.
입력
인자 1 : word
- String 타입의 단어
출력
- int 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- '#' 기호가 없는 경우 -1을 리턴해야 합니다.
입출력 예시
int output = findTheBug("wo#rd");
System.out.println(output); // --> 2
output = findTheBug("#hello");
System.out.println(output); // --> 0
output = findTheBug("bug");
System.out.println(output); // --> -1
힌트
- 모든 문자열의 인덱스는 0부터 시작합니다.
- String타입의 문자열에서 한가지 문자(char)타입의 값을 사용하려면 word.charAt(문자열의 인덱스) 명령어를 사용해야 합니다.
String word = "abcdefg";
System.out.println(word.charAt(0)); // 'a'
System.out.println(word.charAt(2)); // 'c'
System.out.println(word.charAt(5)); // 'f'
public class Solution {
public int findTheBug(String word) {
// TODO:
}
}
정답
package com.choongang;
public class J_FindTheBug {
public int findTheBug(String word) {
// TODO:
// return word.indexOf('#');
int index = -1;
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == '#') {
index = i;
}
}
return index;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class J_FindTheBugTest {
J_FindTheBug test = new J_FindTheBug();
@Test
@DisplayName("\"cup#\"을(를) 입력받은 경우, 3을(를) 리턴해야 합니다")
void findBug() {
assertThat(test.findTheBug("cup#")).isEqualTo(3);
}
@Test
@DisplayName("\"#lizard\"을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void findBug2() {
assertThat(test.findTheBug("#lizard")).isEqualTo(0);
}
@Test
@DisplayName("\"spider\"을(를) 입력받은 경우, -1을(를) 리턴해야 합니다")
void findBug3() {
assertThat(test.findTheBug("spider")).isEqualTo(-1);
}
@Test
@DisplayName("빈 문자열을(를) 입력받은 경우, -1을(를) 리턴해야 합니다")
void findBug4() {
assertThat(test.findTheBug("")).isEqualTo(-1);
}
}
11. countCharacter
문제
문자열과 문자를 입력받아 문자열에서 문자(letter)가 등장하는 횟수를 리턴해야 합니다.
입력
인자 1 : str
- String 타입의 문자열
인자 2 : letter
- char 타입의 문자
출력
- int 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- 빈 문자열을 입력받은 경우, 0을 리턴해야 합니다.
입출력 예시
int output = countCharacter("I am a hacker", 'a');
System.out.println(output); // --> 3
힌트
문자열의 길이는 str.length()를 사용하여 구할 수 있습니다.
String str = "code"
int length = str.length();
System.out.println(length); // 4
public class Solution {
public int countCharacter(String str, char letter) {
// TODO:
}
}
정답
package com.choongang;
public class K_CountCharacter {
public int countCharacter(String str, char letter) {
// TODO:
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == letter) {
count++;
}
}
return count;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class K_CountCharacterTest {
K_CountCharacter test = new K_CountCharacter();
@Test
@DisplayName("차례대로 \"say what!?\",'a'을(를) 입력받은 경우, 2을(를) 리턴해야 합니다")
void countCharacter() {
assertThat(test.countCharacter("say what!?",'a')).isEqualTo(2);
}
@Test
@DisplayName("차례대로 \"say what!?\",' '을(를) 입력받은 경우, 1을(를) 리턴해야 합니다")
void countCharacter2() {
assertThat(test.countCharacter("say what!?",' ')).isEqualTo(1);
}
@Test
@DisplayName("차례대로 \"say what!?\",'x'을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void countCharacter3() {
assertThat(test.countCharacter("say what!?",'x')).isEqualTo(0);
}
@Test
@DisplayName("차례대로 \"\",'a'을(를) 입력받은 경우, 0을(를) 리턴해야 합니다")
void countCharacter4() {
assertThat(test.countCharacter("", 'a')).isEqualTo(0);
}
}
12. getMaxNumberFromString
문제
숫자 문자열을 입력받아 문자열을 구성하는 각 숫자 중 가장 큰 수를 나타내는 숫자를 리턴해야 합니다.
입력
인자 1 : str
- String 타입의 숫자 문자열
출력
- int 타입을 리턴해야 합니다.
주의 사항
- 반복문(for)문을 사용해야 합니다.
- str.split 사용은 금지됩니다.
- 빈 문자열을 입력받은 경우, 0을 리턴해야 합니다.
입출력 예시
int output = getMaxNumberFromString("53862");
System.out.println(output); // --> 8
output = getMaxNumberFromString("4321");
System.out.println(output); // --> 4
public class Solution {
public int getMaxNumberFromString(String str) {
// TODO:
}
}
정답
package com.choongang;
public class L_GetMaxNumberFromString {
public int getMaxNumberFromString(String str) {
// TODO:
int maxNumber = 0;
for (int i = 0; i < str.length(); i++) {
char currentChar = str.charAt(i);
int currentInteger = Character.getNumericValue(currentChar);
if (maxNumber < currentInteger) {
maxNumber = currentInteger;
}
}
return maxNumber;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class L_GetMaxNumberFromStringTest {
L_GetMaxNumberFromString test = new L_GetMaxNumberFromString();
@Test
@DisplayName("\"1234\"을(를) 입력받은 경우, 숫자 4을(를) 리턴해야 합니다")
void getMaxNumberFromString() {
assertThat(test.getMaxNumberFromString("1234")).isEqualTo(4);
}
@Test
@DisplayName("\"12375\"을(를) 입력받은 경우, 숫자 7을(를) 리턴해야 합니다")
void getMaxNumberFromString2() {
assertThat(test.getMaxNumberFromString("12375")).isEqualTo(7);
}
@Test
@DisplayName("빈 문자열을 입력받은 경우, 숫자 0을(를) 리턴해야 합니다")
void getMaxNumberFromString3() {
assertThat(test.getMaxNumberFromString("")).isEqualTo(0);
}
@Test
@DisplayName("\"424257278\"을(를) 입력받은 경우, 숫자 8을(를) 리턴해야 합니다")
void getMaxNumberFromString4() {
assertThat(test.getMaxNumberFromString("424257278")).isEqualTo(8);
}
}
13. replaceAll
문제
문자열과 두 개의 문자(from, to)를 입력받아, 문자열에 등장하는 특정 문자(from)가 다른 문자(to)로 바뀐 문자열을 리턴해야 합니다.
입력
인자 1 : str
- String 타입의 문자열
인자 2 : from
- char 타입의 문자
인자 3 : to
- char 타입의 문자
출력
- String 타입을 리턴해야 합니다.
주의사항
- 반복문(for)문을 사용해야 합니다.
입출력 예시
String output = replaceAll("loop", 'o', 'e');
System.out.println(output); // --> "leep"
public class Solution {
public String replaceAll(String str, char from, char to) {
// TODO:
}
}
정답
package com.choongang;
public class M_ReplaceAll {
public String replaceAll(String str, char from, char to) {
// TODO:
String result = "";
for (int i = 0; i < str.length(); i++) {
char currentChar = str.charAt(i);
if (currentChar == from) {
result += to;
} else {
result += currentChar;
}
}
return result;
}
}
Test
package com.choongang;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class M_ReplaceAllTest {
M_ReplaceAll test = new M_ReplaceAll();
@Test
@DisplayName("차례대로 \"hello\", 'l', 'k'을(를) 입력받은 경우, \"hekko\"을(를) 리턴해야 합니다")
void replaceAll() {
assertThat(test.replaceAll("hello", 'l', 'k')).isEqualTo("hekko");
}
@Test
@DisplayName("차례대로 \"javaworld\", 'a', 'o'을(를) 입력받은 경우, \"jovoworld\"을(를) 리턴해야 합니다")
void replaceAll2() {
assertThat(test.replaceAll("javaworld", 'a', 'o')).isEqualTo("jovoworld");
}
@Test
@DisplayName("차례대로 \"nothing\", 'k', 'a'을(를) 입력받은 경우, \"nothing\"을(를) 리턴해야 합니다")
void replaceAll3() {
assertThat(test.replaceAll("nothing", 'k', 'a')).isEqualTo("nothing");
}
}