본문 바로가기
Language/JAVA

[JAVA] 쉽게 배우는 자바 프로그래밍_5장 문자열, 배열, 열거 타입

by 전전긍긍 2022. 4. 25.

본 포스팅은 쉽게 배우는 자바 프로그래밍 교재를 바탕으로 작성되었습니다.


Chapter 05. 문자열, 배열, 열거 타입

📍도전 과제

01. 학생 수와 점수를 입력하면 각 학생의 성적을 출력하는 프로그램을 작성해 보자.

import java.util.Scanner;

public class Do5_1 {
    public static void main(String[] args) {
        int numOfStudents = 0;
        int [] scores;
        Scanner in = new Scanner(System.in);
        System.out.print("학생 수 ? ");
        numOfStudents = in.nextInt();
        scores = new int[numOfStudents];

        System.out.println(numOfStudents + "명의 학생 성적을 입력하세요.");

        for (int i = 0; i < numOfStudents; i++) {
            scores[i] = in.nextInt();
        }
        System.out.println(numOfStudents + "명의 학생 성적은 다음과 같습니다.");
        for (int i = 0; i < numOfStudents; i++) {
            System.out.print(scores[i] + " ");
        }

    }
}

02. 01번 프로그램을 for문과 if~else문을 사용해 학생들의 등급을 출력하는 프로그램으로 확장해 보자. 그리고 이번에는 for~each문도 사용해 보자.

import java.util.Scanner;

public class Do5_1 {
    public static void main(String[] args) {
        int numOfStudents = 0;
        int[] scores;
        Scanner in = new Scanner(System.in);
        System.out.print("학생 수 ? ");
        numOfStudents = in.nextInt();
        scores = new int[numOfStudents];

        System.out.println(numOfStudents + "명의 학생 성적을 입력하세요.");

        for (int i = 0; i < numOfStudents; i++) {
            scores[i] = in.nextInt();
        }
        System.out.println(numOfStudents + "명의 학생 성적은 다음과 같습니다.");
        /*for (int i = 0; i < numOfStudents; i++) {
            System.out.print(scores[i] + " ");
        }*/
        for (int i : scores)
            System.out.print(i + " ");

        System.out.println();

        for (int i = 0; i < scores.length; i++) {
            if (scores[i] >= 90)
                System.out.println((i + 1) + "번 학생의 등급은 A입니다.");
            else if (scores[i] >= 80)
                System.out.println((i + 1) + "번 학생의 등급은 B입니다.");
            else if (scores[i] >= 70)
                System.out.println((i + 1) + "번 학생의 등급은 C입니다.");
            else if (scores[i] >= 60)
                System.out.println((i + 1) + "번 학생의 등급은 D입니다.");
            else
                System.out.println((i + 1) + "번 학생의 등급은 F입니다.");
        }
    }
}

03. 02의 프로그램에서 등급에 대한 내용을 열거 타입을 사용하여 수정해보자.

import java.util.Scanner;

public class Do5_1 {
    public static void main(String[] args) {
        int numOfStudents = 0;
        int[] scores;
        Scanner in = new Scanner(System.in);
        System.out.print("학생 수 ? ");
        numOfStudents = in.nextInt();
        scores = new int[numOfStudents];

        System.out.println(numOfStudents + "명의 학생 성적을 입력하세요.");

        for (int i = 0; i < numOfStudents; i++) {
            scores[i] = in.nextInt();
        }
        System.out.println(numOfStudents + "명의 학생 성적은 다음과 같습니다.");
        /*for (int i = 0; i < numOfStudents; i++) {
            System.out.print(scores[i] + " ");
        }*/
        for (int i : scores)
            System.out.print(i + " ");

        System.out.println();



        for (int i = 0; i < scores.length; i++) {
            if (scores[i] >= 90)
                System.out.println((i + 1) + "번 학생의 등급은 " + Grade.A + "입니다.");
            else if (scores[i] >= 80)
                System.out.println((i + 1) + "번 학생의 등급은 " + Grade.B + "입니다.");
            else if (scores[i] >= 70)
                System.out.println((i + 1) + "번 학생의 등급은 " + Grade.C + "입니다.");
            else if (scores[i] >= 60)
                System.out.println((i + 1) + "번 학생의 등급은 " + Grade.D + "입니다.");
            else
                System.out.println((i + 1) + "번 학생의 등급은 " + Grade.F + "입니다.");
        }
    }
}
enum Grade {
    A("최우수"), B("우수"), C("보통"), D("미흡"), F("탈락");

    private String s;

    Grade(String s) {
        this.s = s;
    }

    public String toString() {
        return s;
    }
}

📍프로그래밍 문제

01번. 문자열과 문자를 매개변수 값으로 가지는 다음 메서드가 있다. 문자열 s에 포함된 문자 c의 개수를 반환하도록 이 메서드를 구현하라.

 

문자열과 문자를 입력받았다. 입력받은 문자열에서 입력받은 문자가 몇 개인지 출력하는 프로그램을 작성하였다. 

⭐ char형으로 Scanner를 통해 입력을 받으려면 charAt() 메서드를 쓰면 된다.

char c = in.next().charAt(0); //String으로 받고 0번쩨 index가져오기

그리고 for 반복문을 이용해서 문자가 몇 개있는지 개수를 출력하도록 하였다.

import java.util.Scanner;

public class Pro5_01 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.next();
        char c = in.next().charAt(0); //String으로 받고 0번쩨 index가져오기
        System.out.println(s + "에 " + c + "가 " + countChar(s, c) + "개 있다.");
    }

    static int countChar(String s, char c) {
        int x = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == c)
                x++;
        }
        return x;
    }
}

결과

02번. 다음 코드를 실행하면 9, 5, 14를 출력한다. 여기서 sumExceptFirst() 메서드를 하나로 완성하라.

⭐자바는 가변 길이 변수를 배열처럼 취급한다.

한참 고민하다가 결국 구글링하면서 해결했다. 답을 보자마자 wow를 외쳤다. 하루종일 고민했어도 풀지 못했을 것이다. 첫 번째 원소를 따로 두고, 나머지를 가변 길이 변수로 취급한다. 그리고 hint에서 준 것처럼 가변 길이 변수를 배열처럼 취급하니까 arr에 해당하는 부분과 1에 해당하는 부분을 따로 분리하면 된다. arr때문에 한참 고민했는데 등잔 밑이 어둡다는게 이런 것 같다.

public class Pro5_02 {
    public static void main(String[] args) {
        System.out.println(sumExceptFirst(1, 2, 3, 4));
        int arr[] = { 2, 3 };
        System.out.println(sumExceptFirst(1, arr));
        System.out.println(sumExceptFirst(1, 2, 3, 4, 5));
    }
    static int sumExceptFirst(int x, int...y) {
        int sum = 0;
        for (int i : y)
            sum += i;
        return sum;
    }
}

결과

03번. 다음은 main() 메서드와 실행 결과이다. 이를 위한 열거 타입을 작성하라. (자세한 내용은 교재에서)

첫 번쨰 방법. 열거타입상수를 한글로 쓰면 간단하다.

(열거 타입의 상수는 값 대신에 상수의 이름이 출력된다는 점)

public class Pro5_03 {
    public static void main(String[] args) {
        for (Direction d : Direction.values())
            System.out.print(d + " ");
    }
}
enum Direction {동, 서, 남, 북}

두 번째 방법. 동서남북 순서대로 출력되어야 하니, 열거타입상수를 동서남북 순으로 해야 한다. 그리고 문자열을 출력해야 되기 때문에 toString() 메서드를 썼다. 

public class Pro5_03 {
    public static void main(String[] args) {
        for (Direction d : Direction.values())
            System.out.print(d + " ");
    }
}
enum Direction {
    e("동"), w("서"), s("남"), n("북");

    private String x;
    Direction(String x) {
        this.x = x;
    }

    public String toString() {
        return x;
    }
}

결과

04번. 다음과 같이 키보드에서 URL을 입력받은 후 'com'으로 끝나는지, 'java'를 포함하는지 조사하는 프로그램을 작성하라. 'bye'를 입력하면 프로그램은 종료된다.

boolean contains(String s) - 문자열 s를 포함하는지 조사
boolean endsWith(String s) - 끝나는 문자열이 s인지 조사
import java.util.Scanner;

public class Pro5_04 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(true) {
            System.out.print("URL을 입력하세요 : ");
            String url = in.next();

            if (url.equals("bye"))
                break;

            if (url.endsWith("com"))
                System.out.println(url + "은 'com'으로 끝납니다.");
            else
                System.out.println(url + "은 'com'으로 끝나지 않습니다.");

            if (url.contains("java"))
                System.out.println(url + "은 'java'를 포함합니다.");
            else
                System.out.println(url + "은 'java'를 포함하지 않습니다.");

            System.out.println();
        }

    }
}

결과

05번. 0~99 사이의 정수를 키보드에서 10개 입력받아 10단위 간격의 히스토그램을 출력하는 프로그램을 작성하라. 입력된 수가 음수이면 무시하라.

어떻게 하면 코드를 덜 쓸 수 있을까 고민하면서 작성하였다. sum은 참조 변수이기 때문에 일부러 초기화를 하지 않았다. 내가 지금까지 배운 지식으로는 이 정도 코드가 최대의 효율인 것 같다.

import java.util.Scanner;

public class Pro5_05 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int x[] = new int[10];
        int sum[] = new int[10];

        System.out.println("숫자를 10개 입력하세요.");
        for (int i = 0; i < 10; i++) 
            x[i] = in.nextInt();
        
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j ++) {
                if ( x[i] > 0) {
                    if (x[i] / 10 == j)
                        sum[j]++;
                }
                else
                    continue;
            }
        }
        //출력
        for (int i = 0; i < 100; i += 10) {
            System.out.print(i + " ~ " + (int)(i + 9) + " : ");
            for (int j = 0; j < sum[i / 10]; j++) 
                System.out.print("*");
            System.out.println();
        }

    }
}

결과

06번. 주어진 배열의 원소를 역순으로 변환한 배열을 반환하는 다음 메서드를 작성하라.

처음엔 무작정 print(reverse(nums)); 를 했는데, 자꾸 이상한 숫자가 나왔다. 왜인지 생각해보았는데 그 이상한 숫자는 배열의 시작 주소였다. 어차피 배열은 참조하니까 다시 nums를 출력해서 역순으로 변환한 배열이 나오도록 하였다.

import java.util.ArrayList;
import java.util.Scanner;

public class Pro5_6 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[] nums = new int[5];

        for(int i = 0; i < 5; i++)
            nums[i] = in.nextInt();

        reverse(nums);

        for (int i = 0; i < 5; i++)
            System.out.print(nums[i] + " ");
    }
    public static int[] reverse(int[] org) {
        for (int i = 0; i < org.length / 2; i++) {
            int temp = org[i];
            org[i] = org[(org.length - 1) - i];
            org[(org.length - 1) - i] = temp;
        }
        return org;
    }
}

결과

07. 2개의 1차원 배열에서 내용이 같은지를 조사하는 메서드를 정의하고, 다음 배열을 사용해 테스트하라.

1) 길이가 같은지 확인한다. 2) 내용이 같은지 확인한다.

1)은 b같은 경우 때문이다. 길이가 같은지 확인을 안하면 a와 b가 같은 배열인 셈이 된다. 그래서 길이를 확인해주어야 한다.

public class Pro5_07 {
    public static void main(String[] args) {
        int[] a = {3, 2, 4, 1, 5};
        int[] b = {3, 2, 4, 1};
        int[] c = {3, 2, 4, 1, 5};
        int[] d = {2, 7, 1, 8, 2};

        System.out.println(check(a, b)); //f
        System.out.println(check(a, c)); //t
        System.out.println(check(a, d)); //f

        System.out.println(check(b, c)); //f
        System.out.println(check(b, d)); //f

        System.out.println(check(c, d)); //f

    }

    public static boolean check(int[] n1, int[] n2) {

        if (n1.length != n2.length)
            return false;
        for (int i = 0; i < n1.length - 1; i++) {
            if (n1[i] != n2[i])
                return false;
        }
        return true;
    }
}