Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[TIL]20240624 JAVA3주차 다시 시작! 본문

개발Article

[TIL]20240624 JAVA3주차 다시 시작!

최밤빵 2024. 6. 25. 01:13

다형성 부터 꼬여버린 3주차! 오늘 3주차를 다시 공부하기시작.....!

주말동안 4주차까지 들어보는게 목표였는데 프로그래머스 문제풀기와, 3주차를 같이 이해하지 못해서 

주특기 시작인 28일까지 3~4주차를 잘 정리해보기로 계획을 수정했다. 

 

오늘의 페어프로그래밍 문제 리뷰

(+수인님과 페어로 진행. 수인님의 코드도 받아서 저장하고 해석하는 중! 나도 다른 분들처럼 코드를 짜고싶다.)

 

▶ 12번 문제  : 두 정수의 합 

→  문제 그대로 a와 b를 입력받아 a와 b사이의 모든 정수를 더한 값을 반환한다. 같은 수면 둘중 아무 수나 리턴.

class Solution {
    public long solution(int a, int b) {
        long answer = 0;

        if ( a <= b ) {
            for ( int i = a; i <= b; i++)
                answer += i;
        } else {
            for (int i = b; i <= a; i++)
                answer += i;
        }
        return answer;
    }
}

long answer = 0; → 초기화 

if (a <= b) → if 조건문으로 범위를 정해주고, a가 b보다 작거나 같은지 확인. 만약 a가 b보다 작으면 a부터  b까지의 모든

숫자를 더해야 한다. 

 

for (int i = a; i <= b; i++) {

answer += i;

} →  for문으로 i를 a부터 b까지 하나씩 증가시키면서 answer 에 더해준다. 밑 for문은 b부터 a까지 하나씩 증가시키면서 

answer에 더해준다.

ex )숫자 a가 3이고 b가 5일 때 :

a가 b보다 작으니 위 for문 실행.

i = 3 일 때, answer = 0 + 3 = 3

i = 4 일 때, answer = 3 + 4 = 7

i = 5 일 때, answer = 7 + 5=  12 

answer 은 12가 되고 return

▷ 문제와 입출력예시를 읽어보고 수기로 넣어야할 조건문과 반복문을 정리해서 코드로 옮겼다. 

직접 적어보고 코드를 넣어보았다. 생각보다 간단하게 느껴져서 재밌게 풀었다. 

 

▶ 13번 문제 : 콜라츠 추측

→  주어진 숫자 num에 콜라츠 추측을 적용한 후 , 그 과정을 몇 번 반복했는지 반환하는 문제. 

class Solution {
    public int solution(long num) {
        int answer = 0;

        while(num != 1) {
            if(num % 2 == 0)
                num /=2;
            else
                num = num * 3 + 1;
            answer++;

            if(answer >= 500) {
                answer = -1;
                break;
            }
        }
        return answer;
    }
}

int answer = 0; → 초기화 

 

while (num != 1) → while반복문으로 1이 될 때 까지 반복하도록 했다. (조건이 true여야 실행되니까 1이 아닐때를 !=1 로) 

 

if (num % 2 == 0) {

num /= 2;  

} else {

num = num * 3 + 1;

 } → num % 2 로 나머지가 0인수는 짝수. 짝수인지를 확인하는 조건을 넣고, 짝수면 2를 나눈다. 

else는 num이 홀수인 경우로 num = num * 3 + 1; 해준다. 

ex) 숫자 num이 6 일 때 answer은 0

첫 번째 반복,

6은 짝수. 6 / 2 = 3 & answer = 1

두 번째 반복,

3은 홀수. 3 * 3 + 1 = 10 & answer = 2 

세 번째 반복, 

10은 짝수. 10 / 2 = 5 & answer = 3

네 번째 반복,

5는 홀수. 5 * 3 + 1 =16 & answer = 4  

다섯 번째 반복,

16은 짝수. 16 / 2 = 8 & answer = 5

여섯 번째 반복,

8은 짝수. 8 / 2 = 4 & answer = 6

일곱 번째 반복,

4는 짝수. 4 / 2 = 2 & answer = 7

여덟 번째 반복,

2는 짝수. 2 / 2 = 1 & answer = 8 끝! 

answer++; → 각 반복이 끝날 때 마다 반복 횟수를 1씩 증가시킨다.

 

if (answer >= 500) {

answer = -1; break;}} → if로 반복 횟수가 500번 이상인지 확인하고 , 이상이면 answer = -1로 설정하고 

break; 로 반복을 종료시킨다. 

▷ 단지 코드를 만드는 방식을 조금 바꿨을 뿐인데, 문제도 더 잘 읽히고 푸는게 재밌어졌다. 쉬운 난이도의 문제지만

지금은 문제를 보고 어떤 코드를 써야할지 조금씩 안다는부분에서 재미를(?) 느끼는 중, 

 

▶14번 문제 : 서울에서 김서방 찾기 

→ Kim을 찾아서 그 위치를 반환하는 문제. 

class Solution {
    public String solution(String[] seoul) {
        String answer = "";

        for(int i = 0; i < seoul.length; i++) {
            if (seoul[i].equals("Kim")) {
                answer = "김서방은 " + i + "에 있다";
            }
        }
        return answer;
    }
}

String answer = ""; → 초기화. "Kim"의 위치를 저장할 공간.

 

for (int i = 0; i < seoul.length; i++) → i가 0부터 seoul.length보다 작을 때 까지 하나씩 증가하면서 반복.

배열 seoul의 각 요소를 확인한다. 

ex) 배열 seoul이 { "Jane" , " Kim" } 일 때:

첫 번째 반복,

i = 0일 때 seoul[0]은  "Jane" . 다음 반복

두 번째 반복,

i= 1일 때 seoul[1]은  " Kim" . answer은 "김서방은 1에 있다" 끝! 

 

if (seoul[i].equals("Kim")) → seoul의 i번쨰 요소가 "Kim"인지 확인한다. 

 

answer = "김서방은 " + i + "에 있다"; → 찾았으면 문자열을 저장. 

 

break; → 반복문 종료! 

▷ 문제랑 예시 잘 읽었다고 생각했는데.. 쉽게 끝내지 못했다. 처음엔 김서방은 1에 있다. 이 .온점 하나때문에 실행이 안되고, 계속 안되길래 다 찾아보다 Kim의 k를 소문자로 적어서 틀렸다는걸 알게되었다. 문제랑 예시를 똑바로보자... 

배운 것 → 원래는 생각없이 Kim이 같다는걸 '=='으로 하려다가 알게되었다. 

 

" '==' 연산자는 두 객체의 참조 (메모리 주소)가 동일한지를 비교한다 

.equals 메서드는 두 객체의 실제내용을 비교한다.

문자열을 비교할 때는 == 연산자가 아닌 equals 메서드를 사용해야한다. "

 

▶ 15번 문제 : 나누어 떨어지는 숫자 배열 

→ 주어진 배열 arr에서 divisior로 나누어 떨어지는 숫자들을 찾아서 오름차순으로 정렬한 배열을 반환. 

import java.util.*;
class Solution {
    public int[] solution(int[] arr, int divisor) {
        int[] answer = {};
        ArrayList<Integer> a1 = new ArrayList<Integer>();

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] % divisor == 0) {
                a1.add(arr[i]);
            }
        }

        if (a1.isEmpty()) {
            a1.add(-1);
        }

        answer = new int[a1.size()];

        for (int i = 0; i < a1.size(); i++) {
            answer[i] = a1.get(i);
        }

        Arrays.sort(answer);
        return answer;
    }
}

ArrayList<Integer> a1 = new ArrayList<Integer>(); → 나누어 떨어지는 숫자들을 저장할 리스트를 초기화 한다.

 

for (int i = 0; i < arr.length; i++) { 

if (arr[i] % divisor == 0) {

a1.add(arr[i]); } } → for문으로 i 가 0 부터 arr.length보다 작을 때 까지 하나씩 증가하면서 반복. 

if문으로 arr배열의 i번 째 요소가 divisior로 나누어 떨어지는지 확인.

add로 리스트 a1에 추가한다. 

ex) arr = [5, 9, 7, 10], divisor = 5

첫 번째 반복,

arr[0] % 5 == 0. a1에 5 추가 -→ a1 = [5]

두 번째 반복,

arr[1] % 5 != 0 

세 번째 반복,

arr[2] % 5 != 0

네 번째 반복,

arr[3] % 5 == 0. a1에 10 추가 -→ a1 = [5, 10]

 

if (a1.isEmpty()) { a1.add(-1); } → a1이 비어있는지 확인. 비어있으면 -1을 리스트에 추가.

(리스트가 비어있지않기 때문에 추가하지않는다.)

 

answer = new int[a1.size()]; → 리스트를 a1의 크기만큼 answer배열을 초기화.

( [ 0, 0 ] )

 

for (int i = 0; i < a1.size(); i++) { answer[i] = a1.get(i); } → 리스트 a1의 각 요소를 answer 배열에 복사.

(answer = [ 5, 10 ]

 

Arrays.sort(answer); → 배열 정렬. 오름차순으로 정렬해준다.

(answer = [ 5, 10 ])

▷ 문제를 처음보고 오름차순정렬 이 하나에 Arrays.sort를 쓰는거구나! 하면서 리스트로 코드를 만들어 보기로했다. 

컬렉션 부분은 많이 어려워했어서 선언을 또 찾아보고 확인하고 많은 시간을 소요했는데 계속 실행이 안되서 수정의 수정을 반복하고 나중엔 아무리 찾아도 어디가 틀렸는지 모르겠어서, 나와 비슷한 풀이를 한 사람의 답안을 찾아 확인했는데

코드는 맞았지만 import java.util.*;  의 문제였다. 컬렉션 배우면서 꼭 import를 해야한다는 걸 배웠으면서도 인텔리제이가 다 해주니까 놓쳤다. 

 

▶ 16번 문제 : 음양 더하기

→ 정수배열 absolutes와 정수들의 부호를 나타내는 signs배열을 받아서 정수들의 실제값을 계산한 후 합계를 반환. 

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for (int i = 0; i < absolutes.length; i++) {
            if (signs[i] == true) {
                absolutes[i] = absolutes[i];
                answer += absolutes[i];
            } else {
                absolutes[i] = -absolutes[i];
                answer += absolutes[i];
            }
        }
        return answer;
    }
}

int answer = 0; → 0으로 초기화. 최종합계를 저장할 곳. 

 

for (int i = 0; i < absolutes.length; i++)  → i가 0부터 absolutes.length보다 작을 때 까지 하나씩 증가하면서 반복한다.

 

if (signs[i] == true) {

answer += absolutes[i];

} else { answer += -absolutes[i];  } } → 배열의 i요소가 true인지 false인지 확인한다. 

signs[i] == true 면 absolutes[ i ] 를 answer에 더해준다.

signs[i] == false 면 absolutes[i] 에 -를 주고 answer에 더한다. 

 

ex) absolutes = [4, 7, 12], signs = [true, false, true]

첫 번째 반복,

i = 0: signs[0]은 true, 그래서 answer += 4 . answer = 4

두 번째 반복,

i = 1: signs[1]은 false, 그래서 answer += -7 . answer = -3

세 번째 반복,

i = 2: signs[2]는 true, 그래서 answer += 12 . answer = 9 

9반환 끝!

▷ absolutes[i] = absolutes[i]; 이 부분은 생략하면 됐었는데... 문제를 그대로 코드로 옮기자! 에 꽂혀서 그대로 적어버린..

모르고 있다가 페어프로그래밍 하면서 수인님이 콕 찝어 말씀해주셔서 얼굴이 고구마가 됐다. 아.. 이렇게 티가 나나 

그래도 문제만 제대로 읽어도 코드를 생각할 수 있다는 사실은 나를 즐겁게한다😆

 

▶ 17번 문제 : 핸드폰 번호 가리기 

→ 마지막  4자리 빼고 * 로 대체하기.

class Solution {
    public String solution(String phone_number) {
        String answer = "";
        String[] x = phone_number.split("");
        for (int i = 0; i < x.length; i++) {
            if (i < (x.length - 4)) {
                answer += "*";
            } else {
                answer += x[i];
            }
        }
        return answer;
    }
}

String answer = ""; → 빈 문자열 변수 초기화 

 

String[] x = phone_number.split(""); → 전화번호 문자열을 각 문자 단위로 쪼개서 배열 x에 저장.

 

for (int i = 0; i < x.length; i++) → i가 0부터 x.length보다 작을 때 까지 하나씩 증가하면서 반복. 배열 x

 

if (i < (x.length - 4)) {

 } else {

 answer += x[i]; }} → i가 마지막 4자리 이전인지 확인.

if (i < (x.length - 4)) 조건이 true면 answer에 *을 추가 

 

answer += x[i]; → 위 조건에 부합하지않으면, 그러니까 마지막 4자리라면 answer에 원래 문자를 추가. 

▷ 나는 자꾸 뭐 하나에 꽂히는 걸 좀 고쳐야된다. 도저히 저 -4가 이해되지 않아서 수인님께 여쭤봤는데 그대로 보면 된다고 했지만, 이미 별별 생각을 다하던 중이라 그대로 보이지않아서 애를먹었다. 

그냥 문자열의 길이에서 4을 빼서 마지막 4자리만 제외한다고 생각하면 된다구!!!! 

 

3주차 정리 

(초반부분만 정리하기로!)

 

1. 클래스 작성

2. 객체 생성

3. 객체 사용

 

▶ 객체의 생성과 사용

클래스명 변수명; 

클래스의 객체를 참조하기 위한 참조변수를 선언.

변수명 = new 클래스명();

클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장. 

Tv t ;

t = new Tv();

public class Practice {
    public static void main(String[] args) {
        Tv t;
        t = new Tv();
        t.channel = 7;
        t.channelDown();
        System.out.println("현재 채널은" + t.channel + "입니다.");
    }
}

 

public class Tv {

    String color;
    boolean power;
    int channel;

    void power() {
        power = !power;
    }
    void channelUp() {
        channel++;
    }
    void channelDown() {
        channel--;
    }
}

▶ 예제

public class Practice {
    public static void main(String[] args) {
        Tv t1 = new Tv();
        Tv t2 = new Tv();
        System.out.println("t1의 channel값은" + t1.channel + "입니다.");
        System.out.println("t2의 channel값은" + t2.channel + "입니다.");

        t2 = t1;
        t1.channel = 7;
        System.out.println("t1의 channel값을 7로 변경하였습니다.");

        System.out.println("t1의 channel값은" + t1.channel + "입니다.");
        System.out.println("t2의 channel값은" + t2.channel + "입니다.");
    }
}

t2는 t1과 같은 값의 주소를 갖게된다. 

하나의 인스턴스를 여러개의 참조변수가 가리키는 경우 (가능)

여러 인스턴스를 하나의 참조변수가 가리키는 경우 (불가능) 

 

▶ 선언 위치에 따른 변수의 종류

멤버변수를 제외한 나머지 변수들은 모두 지역변수이며, 멤버 변수중 static이 붙은것은 클래스 변수, 붙지 않은 것은 인스턴스 변수이다. 

 

1. 인스턴스 변수 : 클래스 영역에 선언. 인스턴스를 생성할 때 만들어 진다. 그래서 값을 읽어오거나 저장하려면 먼저 인스턴스를 생성해야한다. 인스턴스마다 별도의 저장공간을 가지므로 서로 다른 값을 가질 수 있다. 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스 변수로 선언. 

2. 클래스 변수 : 클래스 변수를 선언하는 방법은 인스턴스 변수 앞에 static을 붙이기만 하면 된다. 인스턴스마다 독립적인 저장공간을 갖는 인스턴스 변수와는 달리, 클래스 변수는 모든 인스턴스가 공통된 저장공간(변수)을 공유하게 된다. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 클래스 변수로 선언해야 한다. 클래스 변수는 언제라도 바로 사용할수 있다 .

 

" 인스턴스 변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만,

클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다."

public class Card {

    String kind;
    int number;

    static int width = 100;
    static int height = 250;
    
}

 

 

😊오늘의 회고 

 문제를 어떻게 푸시는지 여쭤보고 나도 그대로 실행해봤는데, 그랬을뿐인데 예전 문제를 잘 읽지도 않았던 나여서그런가 큰 변화같이 느껴진다. 수기로해보고 고민도하고 이 메서드를 써야겠다!! 아는거나왔다!! 이런 느낌이라 재밌게 문제풀이를 했다. 는 1~2문제였고 그냥 하던식으로 할걸.. 싶은 문제도 있었고, 어려워서 생각도하기싫은 그냥 답안보고 싶다! 하고싶은 문제도 있었지만.. 지금의 나는 너무 허접해서 학습을위해 참았다.. 그래도 메서드나 이렇게 하면 되겠다 라는 생각을 떠올린 자체를 내가 조금 컸구나! 신생아에서 옹알이정도는 하는 수준이 되지 않았을까? 라고 혼자 칭찬 중. 사실 풀어왔던 문제들에서 배운거고, 조건 방식이 비슷해서 큰 어려움없이 푼 거 같지만 지금 이정도도 나는 잘하고 있는거라고 생각하기로했다. TIL을 쓰면서 문제를 해석하며 또 푸느라 많은 시간을 썼다. 시간이 아깝다기보다 재밌을줄알았는데... 푼 문제를 또 고민을 하고 있는 나. 그래도 괜찮다. 이것도 공부니까. 다시 3주차 들으러 갑니다! 계속하다보면 언젠간 조금이라도 이해하겠지!