본문 바로가기
개념

[JAVA의 정석] Chapter09_연습문제

by cook_code 2024. 12. 15.
 

[9-1] 다음과 같은 실행결과를 얻도록 SutdaCard클래스의 equal( )를 멤버변수인 num, isKwang의 값을 비교하도록 오버라이딩하고 테스트하시오.

 

c1=3K

c2=3K

c1.equals(c2):true

 

public class Exercise9_1 {
	public static void main(String[] args) {
		SutdaCard c1 = new SutdaCard(3, true);
		SutdaCard c2 = new SutdaCard(3, true);
		System.out.println("c1=" + c1);
		System.out.println("c2=" + c2);
		System.out.println("c1.equals(c2):" + c1.equals(c2));
	}
}

class SutdaCard {
	int num;
	boolean isKwang;

	SutdaCard() {
		this(1, true);
	}

	SutdaCard(int num, boolean isKwang) {
		this.num = num;
		this.isKwang = isKwang;
	}

	public boolean equals(Object obj) {
		if (obj instanceof SutdaCard) {
			SutdaCard c = (SutdaCard) obj;
			return num == c.num && isKwang == c.isKwang;
		}
		return false;
	}

	public String toString() {
		return num + (isKwang ? "K" : "");
	}
}
 

풀이

1. obj가 SutdaCard의 인스턴스인지 확인합니다.
2. SutdaCard 객체로 형변환합니다.
3. num과 isKwang이 모두 같은지 비교합니다.
4. 같으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
 

[9-2] 다음과 같은 실행결과를 얻도록 Point3D 클래스의 equals( )를 멤버변수인 x, y, z의 값을 비교하도록 오버라이딩하고, toString( )은 실행결과를 참고해서 적절히 오버라이딩하시오.

 

[1,2,3]

[1,2,3]

p1==p2?false

p1.equals(p2)?true

 

class Exercise9_2 {
	public static void main(String[] args) {
		Point3D p1 = new Point3D(1, 2, 3);
		Point3D p2 = new Point3D(1, 2, 3);
		System.out.println(p1);
		System.out.println(p2);
		System.out.println("p1==p2?" + (p1 == p2));
		System.out.println("p1.equals(p2)?" + (p1.equals(p2)));
	}
}

class Point3D {
	int x, y, z;
	Point3D(int x, int y, int z) {
		this.x = x;
		this.y = y;
		this.z = z;
	}
	Point3D() {
		this(0, 0, 0);
	}

	public boolean equals(Object obj) {
		/* (1) 인스턴스변수 x, y, z를 비교하도록 오버라이딩하시오. */
		if (obj instanceof Point3D) {
			Point3D p = (Point3D) obj;
			return x == p.x && y == p.y && z == p.z;
		}
		return false;
	}

	public String toString() {
		/* (2) 인스턴스변수 x, y, z의 내용을 출력하도록 오버라이딩하시오 . */
		return "[" + x + ", " + y + ", " + z + "]";
	}
}
 

[9-3] 다음과 같은 실행결과가 나오도록 코드를 완성하시오.

 

fullPath:c:\jdk1.8\work\PathSeparateTest.java

path:c:\jdk1.8\work

fileName:PathSeparateTest.java

 

class Exercise9_3 {
    public static void main(String[] args) {
        String fullPath = "c:\\jdk1.8\\work\\PathSeparateTest.java";
        String path = "";
        String fileName = "";

        /* (1) 알맞은 코드를 넣어 완성하시오  . */
        int pos = fullPath.lastIndexOf("\\");
        if (pos != -1) {
            path = fullPath.substring(0, pos);
            fileName = fullPath.substring(pos + 1);
        }
        System.out.println("fullPath:" + fullPath);
        System.out.println("path:" + path);
        System.out.println("fileName:" + fileName);
    }
}
 

풀이

// 파일 경로 문자열에서 경로와 파일 이름을 분리하여 출력하는 프로그램 

1. fullPath.lastIndexOf("\\"): 전체 경로에서 마지막 \\ 문자의 위치를 찾기
2. pos: 마지막 \\ 문자의 위치를 저장
3. if (pos != -1): \\ 문자가 존재하면 다음 코드를 실행
4. path = fullPath.substring(0, pos): 경로 부분을 추출하여 path 변수에 저장
5. fileName = fullPath.substring(pos + 1): 파일 이름 부분을 추출하여 fileName 변수에 저장
 

[9-4] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

메서드명:printGraph

기능:주어진 배열에 담긴 값만큼 주어진 문자를 가로로 출력한 후, 값을 출력한다.

반환타입:없음

매개변수:int[ ] dataArr - 출력할 그래프의 데이터

char ch - 그래프로 출력할 문자

 

***3

*******7

*1

****4

 

class Exercise9_4 {
    static void printGraph(int[] dataArr, char ch) {
        for (int i = 0; i < dataArr.length; i++) {
            for (int j = 0; j < dataArr[i]; j++) {
                System.out.print(ch);
            }
            System.out.print(dataArr[i] + " ");
            System.out.println();
        }
    }
    public static void main(String[] args) {
        printGraph(new int[] { 3, 7, 1, 4 }, '*');
    }
}
 

[9-5] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

[Hint] String 클래스의 indexOf(String str, int fromIndex)를 사용할 것

 

메서드명:count

기능:주어진 문자열(src)에 찾으려는 문자열(target)이 몇 번 나오는지 세어서 반환한다.

반환타입:int

매개변수

- String src

- String target

 

3

0

 

class Exercise9_5 {
    public static int count(String src, String target) {
        int count = 0; // 찾은 횟수
        int pos = 0; // 찾기 시작할 위치
        /*
         * (1) 반복문을 사용해서 아래의 과정을 반복한다 .
         * 1. src에서 target을 pos의 위치부터 찾는다.
         * 2. 찾으면 count의 값을 1 증가 시키고,
         * 	  pos의 값을  target.length만큼 증가시킨다.
         * 3. indexOf의 결과가 -1이면 반복문을 빠져나가서 count를 반환한다.
         */
        while(true){
            pos = src.indexOf(target, pos);
            if(pos == -1) break;
            if(src.substring(pos,pos+target.length()).equals(target)){
                pos += target.length();
                count++;
            }
        }
        return count;
    }
    public static void main(String[] args) {
        System.out.println(count("12345AB12AB345AB", "AB"));
        System.out.println(count("12345", "AB"));
    }
}
 

[9-6] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

 

메서드명:fillZero

기능:주어진 문자열(숫자)로 주어진 길이의 문자열로 만들고, 왼쪽 빈 공간은 '0'으로 채운다.

만일 주어진 문자열이 null이거나 문자열의 길이가 length의 값과 같으면 그대로 반환한다.

만일 주어진 length의 값이 0보다 길거나 작은 값이면, 빈 문자열("")을 반환한다.

반환타입:String

매개변수

- String src - 변환할 문자열

- int length - 변환할 문자열의 길이

 

0000012345

123

 

// 풀이 1 : Arrays 클래스 활용
import java.util.Arrays;

class Exercise9_6 {
    public static String fillZero(String src, int length) {
         /* (1) fillZero 메서드를 작성하시오 .
         * 1. src가 널이거나 src.length()가 length와 같으면 src를 그대로 반환한다.
         * 2. length의 값이 0보다 같거나 작으면 빈 문자열("")을 반환한다.
         * 3. src의 길이가 length의 값보다 크면 src를 length만큼 잘라서 반환한다.
         * 4. 길이가 length인 char배열을 생성한다.
         * 5. 4에서 생성한 char배열을 '0'으로 채운다.
         * 6. src에서 문자배열을 뽑아내서 4에서 생성한 배열에 복사한다.
         * 7. 4에서 생성한 배열로 String을 생성해서 반환한다.
         */
        if (src == null || length <= 0) return ""; // length가 0보다 작거나 같은 경우 빈 문자열 반환
        if (src.length() == length) return src; // src의 길이가 length와 같은 경우 그대로 반환
        if (src.length() > length) return src.substring(0, length); // src의 길이가 length보다 큰 경우 자르기

        char[] chars = new char[length];
        Arrays.fill(chars, '0'); // char 배열을 '0'으로 채우기
        System.arraycopy(src.toCharArray(), 0, chars, length - src.length(), src.length()); // src 배열 복사
        return new String(chars); // char 배열을 String으로 변환 후 반환
    }

    public static void main(String[] args) {
        String src = "12345";
        System.out.println(fillZero(src, 10)); // "0000012345"
        System.out.println(fillZero(src, -1)); // ""
        System.out.println(fillZero(src, 3)); // "123"
    }
}


// 풀이 2 : 배열로만 작업
class Exercise9_6 {
    public static String fillZero(String src, int length) {
        if (src == null || length <= 0) return ""; // length가 0보다 작거나 같은 경우 빈 문자열 반환
        if (src.length() == length) return src; // src의 길이가 length와 같은 경우 그대로 반환
        if (src.length() > length) return src.substring(0, length); // src의 길이가 length보다 큰 경우 자르기

        char[] chars = new char[length];
        // char 배열을 '0'으로 채우기
        for (int i = 0; i < chars.length; i++) {
            chars[i] = '0';
        }
        // src 배열 복사
        for (int i = 0; i < src.length(); i++) {
            chars[length - src.length() + i] = src.charAt(i);
        }
        return new String(chars); // char 배열을 String으로 변환 후 반환
    }

    public static void main(String[] args) {
        String src = "12345";
        System.out.println(fillZero(src, 10)); // "0000012345"
        System.out.println(fillZero(src, -1)); // ""
        System.out.println(fillZero(src, 3)); // "123"
    }
}
 

[9-7] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

[Hint] String클래스의 indexOf( )를 사용할 것

 

메서드명:contains

기능:첫 번째 문자열(src)에 두 번째 문자열(target)이 포함되어 있는지 확인한다.

포함되어 있으면 true, 그렇지 않으면 false를 반환한다.

반환타입:boolean

매개변수:

- String src

- String target

 

true

false

 

class Exercise9_7 {
    /* (1) contains 메서드를 작성하시오 . */
    static boolean contains(String src, String target) {
        /* 첫 번째 문자열(src)에 두 번째 문자열(target)이 포함되어 있는지 확인한다.
           포함되어 있으면 true, 그렇지 않으면 false를 반환한다. */
        return src.indexOf(target) != -1;
    }

    public static void main(String[] args) {
        System.out.println(contains("12345", "23"));
        System.out.println(contains("12345", "67"));
    }
}
 

풀이

1. contains 메서드 호출: contains("12345", "23")
- src.indexOf(target) 호출: "12345".indexOf("23")는 2를 반환 ("23" 문자열이 "12345"의 인덱스 2에서 시작하기 때문).
- 2 != -1이므로 true를 반환.
- 출력: true

2. contains 메서드 호출: contains("12345", "67")
- src.indexOf(target) 호출: "12345".indexOf("67")는 -1을 반환 ("67" 문자열이 "12345"에 포함되어 있지 않기 때문).
- -1 != -1이므로 false를 반환.
- 출력: false
 

[9-8] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

 

메서드명:round

기능:주어진 값을 반올림하여, 소수점 이하 n자리의 값을 반환한다.

예를 들어 n의 값이 3이면, 소수점 4째 자리에서 반올림하여 소수점 이하 3자리의 수를 반환한다.

반환타입:double

매개변수:double d - 변환할 값

int n - 반올림한 결과의 소수점 자리

[Hint] Math.round( )와 Math.pow( )를 이용하라.

 

3.1

3.14

3.142

3.1415

3.1415

 

class Exercise9_8 {
    public static double round(double d, int n){
        double num = Math.pow(10.0, (double)n);
        return Math.round(d*num)/num;
    }
    /* (1) round 메서드를 작성하시오 . */
    public static void main(String[] args) {
        System.out.println(round(3.1415, 1));
        System.out.println(round(3.1415, 2));
        System.out.println(round(3.1415, 3));
        System.out.println(round(3.1415, 4));
        System.out.println(round(3.1415, 5));
    }
}
 

[9-9] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

[Hint] StringBuffer와 String클래스의 charAt(int i)과 indexOf(int ch)를 사용하라.

 

메서드명:delChar

기능:주어진 문자열에서 금지된 문자들을 제거하여 반환한다.

반환타입:String

매개변수:

- String src - 변환할 문자열

- String delCh - 제거할 문자들로 구성된 문자열

 

(1!2@3^4~5) -> 12345

(1 2 3 4 5) -> (12345)

 

class Exercise9_9 {
    /* (1) delChar 메서드를 작성하시오 . */
    public static String delChar(String src, String delCh) {
        StringBuffer sb = new StringBuffer(src);
        for (int i = 0; i < delCh.length(); i++) {
            int pos = 0;
            while (pos < src.length()) {
                int newPos = src.indexOf(delCh.charAt(i), pos);
                if (newPos == -1)
                    break;
                else {
                    sb.deleteCharAt(newPos);
                    src = sb.toString();
                }
                pos = newPos;
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println("(1!2@3^4~5)" + " -> "
                + delChar("(1!2@3^4~5)", "~!@#$%^&*()"));
        System.out.println("(1 2 3 4\t5)" + " -> "
                + delChar("(1 2 3 4\t5)", " \t"));
    }
}
 

[9-10] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

 

메서드명:format

기능:주어진 문자열을 지정된 크기의 문자열로 반환한다. 나머지 공간은 공백으로 채운다.

반환타입:String

매개변수:

String str - 변환할 문자열

int length - 변환된 문자열의 길이

int alignment - 변환된 문자열의 정렬조건

(0: 왼쪽정렬, 1: 가운데 정렬, 2: 오른쪽 정렬)

 

가나다

가나다

가나다

 

class Exercise9_10 {
    /*
     * format 메서드를 작성하시오.
     * 1. length의 값이 str의 길이보다 작으면 length만큼만 잘라서 반환한다.
     * 2. 1의 경우가 아니면, length크기의 char배열을 생성하고 공백으로 채운다.
     * 3. 정렬조건 (alignment)의 값에 따라 문자열 (str)을 복사할 위치를 결정한다.
     *  (System.arraycopy()사용 )
     *  4. 2에서 생성한 char배열을 문자열로 만들어서 반환한다.
     */

    public static String format(String str, int length, int alignment) {
        if (length < str.length()) {
            return str.substring(0, length); // 문자열이 지정된 길이보다 길면 잘라서 반환
        }

        char[] arr = new char[length]; // 길이에 맞는 char 배열 생성
        for (int i = 0; i < length; i++) {
            arr[i] = ' '; // 배열을 공백으로 초기화
        }

        int start = 0;
        if (alignment == 0) { // 왼쪽 정렬
            start = 0;
        } else if (alignment == 1) { // 가운데 정렬
            start = (length - str.length()) / 2;
        } else if (alignment == 2) { // 오른쪽 정렬
            start = length - str.length();
        }

        System.arraycopy(str.toCharArray(), 0, arr, start, str.length());
        return new String(arr); // char 배열을 문자열로 변환 후 반환
    }

    public static void main(String[] args) {
        String str = "가나다";
        System.out.println( format(str, 7, 0) ); // 왼쪽 정렬
        System.out.println( format(str, 7, 1) ); // 가운데 정렬
        System.out.println( format(str, 7, 2) ); // 오른쪽 정렬
    }
}
 

[9-11] 커맨드라인으로 2~9사이의 두 개의 숫자를 받아서 두 숫자사이의 구구단을 출력하는 프로그램을 작성하시오. 예를 들어 3과 5를 입력하면 3단부터 5단까지 출력한다.

 

import java.util.InputMismatchException;
import java.util.Scanner;

class Exercise9_11 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("java Exercise9_11 ");
        System.out.println("시작 단과 끝 단, 두 개의 정수를 입력해주세요.");
        try {
            do {
                int startDan = sc.nextInt();
                int endDan = sc.nextInt();

                System.out.println(startDan);
                System.out.println(endDan);

                if (startDan < 1 || startDan > 9 || endDan < 1 || endDan > 9) {
                    System.out.println("단의 범위는 2와 9사이의 값이어야 합니다.");
                    continue;
                } else {
                    System.out.println("구구단 로직 시작");
                    // 구구단 로직 시작
                    for (int i = startDan; i <= endDan; i++) {
                        for (int j = 1; j <= 9; j++) {
                            System.out.print(i + "*" + j + "=" + (i * j));
                            System.out.println();
                        }
                    }
                }
            } while (true);
        } catch (InputMismatchException e) {
            e.printStackTrace();
        }

    }
}
 

[9-12] 다음과 같이 정의된 메서드를 작성하고 테스트하시오.

[주의] Math.random( )을 사용하는 경우 실행결과와 다를 수 있음.

[Hint] Math.random( )과 절대값을 반환하는 Math.abs(int a), 그리고 둘 중에 작은 값을 반환하는 Math.min(int a, int b)를 사용하라.

 

메서드명:getRand

기능:주어진 범위(from~to)에 속한 임의의 정수값을 반환한다.

(양쪽 경계값 모두 범위에 포함)

from의 값이 to의 값보다 클 경우도 처리되어야 한다.

반환타입:int

매개변수:

int from - 범위의 시작값

int to - 범위의 끝값

 

0,-1,1,0,-2,-2,1,1,-3,0,-1,1,1,1,0,-1,1,0,-1,-3,

class Exercise9_12 {
    /* (1) getRand 메서드를 작성하시오 . */
    static int getRand(int from, int to) {
        // from이 to보다 클 경우 값을 바꾼다
        int min = Math.min(from, to);
        int max = Math.max(from, to);
        return (int) (Math.random() * (max - min + 1)) + min;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            System.out.print(getRand(1, -3) + ",");
        }
    }
}
 

[9-13] 다음은 하나의 긴 문자열(source) 중에서 특정 문자열과 일치하는 문자열의 개수를 구하는 예제이다. 빈 곳을 채워 예제를 완성하시오.

 

aabbccAABBCCaa

aa를 2개 찾았습니다.

 

public class Exercise9_13 {
    public static void main(String[] args) {
        String src = "aabbccAABBCCaa";
        System.out.println(src);
        System.out.println("aa를 " + stringCount(src, "aa") + " 개 찾았습니다 .");
    }
    static int stringCount(String src, String key) {
        return stringCount(src, key, 0);
    }
    static int stringCount(String src, String key, int pos) {
        int count = 0;
        int index = 0;
        if (key == null || key.length() == 0)
            return 0;
        while((index = src.indexOf(key,pos))!=-1) {
            count++;
            pos = index + key.length();
        }
        return count;
    }
}
 

[9-14] 다음은 화면으로부터 전화번호의 일부를 입력받아 일치하는 전화번호를 주어진 문자열 배열에서 찾아서 출력하는 프로그램이다. 알맞은 코드를 넣어 프로그램을 완성하시오.

[Hint] Pattern, Matcher클래스를 사용할 것

 

>>

>>

>>asdf

일치하는 번호가 없습니다.

>>

>>

>>0

[012-3456-7890,099-2456-7980,088-2346-9870,013-3456-7890]

>>234

[012-3456-7890,088-2346-9870]

>>7890

[012-3456-7890,013-3456-7890]

>>q

 

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Exercise9_14 {
    public static void main(String[] args) {
        String[] phoneNumArr = { "012-3456-7890", "099-2456-7980",
                "088-2346-9870", "013-3456-7890" };
        ArrayList<String> list = new ArrayList<>();
        Scanner s = new Scanner(System.in);
        while (true) {
            System.out.print(">>");
            String input = s.nextLine().trim();
            if (input.equals("")) {
                continue;
            } else if (input.equalsIgnoreCase("Q")) {
                System.exit(0);
            }

            // 패턴을 생성하여 입력된 문자열이 포함된 전화번호를 찾기
            Pattern p = Pattern.compile(input);
            for (String phoneNum : phoneNumArr) {
                Matcher m = p.matcher(phoneNum);
                if (m.find()) {
                    list.add(phoneNum);
                }
            }
            if (list.size() > 0) {
                System.out.println(list);
                list.clear();
            } else {
                System.out.println("일치하는 번호가 없습니다.");
            }
        }
    }
}
 

풀이

1. 패턴 컴파일 및 매처 생성
Pattern p = Pattern.compile(input);
입력된 문자열 input을 패턴으로 컴파일합니다.
Matcher m = p.matcher(phoneNum);
주어진 전화번호 phoneNum과 패턴을 비교하기 위한 매처를 생성합니다.

2. 일치하는 전화번호 찾기
if (m.find()) { list.add(phoneNum); }
매처 m을 사용하여 phoneNum에서 패턴이 일치하는지 확인하고, 일치하면 list에 추가합니다.

3. 결과 출력 및 리스트 초기화
if (list.size() > 0) { System.out.println(list); list.clear(); }
list에 일치하는 전화번호가 있으면 출력하고, 리스트를 초기화합니다.
else { System.out.println("일치하는 번호가 없습니다."); }
list가 비어있으면 일치하는 번호가 없다는 메시지를 출력합니다.
 

 

반응형