반응형

등등...

2023년에 서류탈락한 기업만 50개가 넘는다

그 중, 면접까지 간 기업은 단 3개... 하나는 인턴을 했지만 결국 최종면접에서 탈락했고, 나머지 두 발의 총알마저 무산되었다.

 

삼성, 엘지, 포스코 모두 서류는 뚫었지만 인적성에서 탈락했다.. 내 공부방법이 너무 안일했던 탓이다

 

뭐 어쩌겠나, 다시 시작해야지

 

멘탈잡자

반응형
반응형

https://www.acmicpc.net/problem/10811

 

10811번: 바구니 뒤집기

도현이는 바구니를 총 N개 가지고 있고, 각각의 바구니에는 1번부터 N번까지 번호가 순서대로 적혀져 있다. 바구니는 일렬로 놓여져 있고, 가장 왼쪽 바구니를 1번째 바구니, 그 다음 바구니를 2

www.acmicpc.net

문제

도현이는 바구니를 총 N개 가지고 있고, 각각의 바구니에는 1번부터 N번까지 번호가 순서대로 적혀져 있다. 바구니는 일렬로 놓여져 있고, 가장 왼쪽 바구니를 1번째 바구니, 그 다음 바구니를 2번째 바구니, ..., 가장 오른쪽 바구니를 N번째 바구니라고 부른다.

도현이는 앞으로 M번 바구니의 순서를 역순으로 만들려고 한다. 도현이는 한 번 순서를 역순으로 바꿀 때, 순서를 역순으로 만들 범위를 정하고, 그 범위에 들어있는 바구니의 순서를 역순으로 만든다.

바구니의 순서를 어떻게 바꿀지 주어졌을 때, M번 바구니의 순서를 역순으로 만든 다음, 바구니에 적혀있는 번호를 가장 왼쪽 바구니부터 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 N (1 ≤ N ≤ 100)과 M (1 ≤ M ≤ 100)이 주어진다.

둘째 줄부터 M개의 줄에는 바구니의 순서를 역순으로 만드는 방법이 주어진다. 방법은 i j로 나타내고, 왼쪽으로부터 i번째 바구니부터 j번째 바구니의 순서를 역순으로 만든다는 뜻이다. (1 ≤ i ≤ j ≤ N)

도현이는 입력으로 주어진 순서대로 바구니의 순서를 바꾼다.

 

출력

모든 순서를 바꾼 다음에, 가장 왼쪽에 있는 바구니부터 바구니에 적혀있는 순서를 공백으로 구분해 출력한다.

 

접근 방법

* 도현이는 바구니를 총 N개 가지고 있고, 각각의 바구니에는 1번부터 N번까지 번호가 순서대로 적혀져 있다.

-> 크기가 N+1인 배열을 만들고, 각 인덱스의 데이터를 인덱스 번호로 초기화한다.
    '순서대로' 적혀 있다고 했으니 1차원 배열을 써도 무난하겠다고 판단!!
    int[] arr = new int[N+1]; // arr[0]을 낭비하긴 하지만, 문제를 해결하는데 있어 편하게 하기 위해서!!

 

* 바구니는 일렬로 놓여져 있고, 가장 왼쪽 바구니를 1번째 바구니, 그 다음 바구니를 2번째 바구니, ..., 가장 오른쪽 바구니를 N번째 바구니라고 부른다. 도현이는 앞으로 M번 바구니의 순서를 역순으로 만들려고 한다. 도현이는 한 번 순서를 역순으로 바꿀 때, 순서를 역순으로 만들 범위를 정하고, 그 범위에 들어있는 바구니의 순서를 역순으로 만든다.

-> 그림과 같이 i는 1씩 증가를, j는 1씩 감소를 하며 양 끝에 있는 값끼리 위치를 바꿔준다. 그리고 i가 j보다 작아질 때라는 조건을 부여하여 탈출 조건을 작성한다.

 

* 바구니의 순서를 어떻게 바꿀지 주어졌을 때, M번 바구니의 순서를 역순으로 만든 다음, 바구니에 적혀있는 번호를 가장 왼쪽 바구니부터 출력하는 프로그램을 작성하시오.

 

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);
        // 1. N+1 크기의 배열을 만든다. index를 다루기 편하게 하기 위함
        int N = sc.nextInt();
        int M = sc.nextInt();
        int[] arr = new int[N+1];

        // 2. 각 배열의 초기값을 index값과 일치하게 초기화
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }

        for (int k = 0; k < M; k++) {
            int i = sc.nextInt();
            int j = sc.nextInt();

            while (i < j) {
                int temp = arr[i];
                arr[i++] = arr[j];
                arr[j--] = temp;
            }
        }

        for (int answer : arr) {
            if(answer != 0)
                System.out.print(answer + " ");
        }

    }
}

 

정리

while문을 사용하여 양 끝단에서 한 칸씩 줄어들며 버블정렬을 하면 쉽게 풀 수 있는 문제이다.

 

회고

처음에 for 문 안에 i와 j 두 값을 한번에 바꿀 수 없을까?하는 생각에 잠겨서 30분 정도 고민했던 것 같다. 길을 잘못들어섰으면 빨리 뒤돌아서 다른 방법을 찾는 것도 하나의 방법!

 

반응형
반응형

https://www.acmicpc.net/problem/5597

 

5597번: 과제 안 내신 분..?

X대학 M교수님은 프로그래밍 수업을 맡고 있다. 교실엔 학생이 30명이 있는데, 학생 명부엔 각 학생별로 1번부터 30번까지 출석번호가 붙어 있다. 교수님이 내준 특별과제를 28명이 제출했는데,

www.acmicpc.net

문제

X대학 M교수님은 프로그래밍 수업을 맡고 있다. 교실엔 학생이 30명이 있는데, 학생 명부엔 각 학생별로 1번부터 30번까지 출석번호가 붙어 있다. 교수님이 내준 특별과제를 28명이 제출했는데, 그 중에서 제출 안 한 학생 2명의 출석번호를 구하는 프로그램을 작성하시오.

 

입력

입력은 총 28줄로 각 제출자(학생)의 출석번호 n(1 ≤ n ≤ 30)가 한 줄에 하나씩 주어진다. 출석번호에 중복은 없다.

 

출력

출력은 2줄이다. 1번째 줄엔 제출하지 않은 학생의 출석번호 중 가장 작은 것을 출력하고, 2번째 줄에선 그 다음 출석번호를 출력한다. (예제 입력은 밑에 더 있다. 보기가 길어질까봐 잘랐음)

 

접근 방법

- 1차원 배열로 쉽게 풀 수 있는 문제이다. 그런데, list를 사용해서 sort를 해서 풀 수 있겠다는 생각이 들었고, 두 방법으로 모두 풀어보았다.

 


1. 1차원 배열을 사용한 풀이

import java.io.*;
import java.util.*;
public class Main {
    public static void main(String args[]) {

        Scanner sc = new Scanner(System.in);
        int[] arr = new int[31];

        for (int i = 0; i < 28; i++) {
            int input = sc.nextInt();
            arr[input] = 1;
        }

        for (int j = 1; j < arr.length; j++) {
            if (arr[j] != 1) {
                System.out.println(j);
            }
        }

        sc.close();
    }
}

1차원 배열을 생성하여, for문을 28번 돌리며 각 시행마다 input값을 받아서 그것에 해당하는 배열 인덱스의 값을 1로 지정한다. 그리고 다음 번 for문에서 배열의 원소가 1이 아닌 값을 출력한다.

장점 : 1차원 배열을 사용했기 때문에 순서가 정해져있다. 즉, sort를 할 필요 없이 오름차순으로 출력할 수 있다.

단점 : 수행 시간이 조금 걸린다(근데 이 문제에서는 크게 신경안써도 될 듯..!)

 

2. ArrayList를 사용한 풀이

import java.io.*;
import java.util.*;
public class Main {
    public static void main(String args[]) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        List<Integer> alist = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        
        for (int j = 0; j < 28; j++) {
            int numlist = Integer.parseInt(br.readLine());
            alist.add(numlist);
        }

        for (int i = 1; i <= 30; i++) {
            if (!alist.contains(i)) {
                list.add(i);
            }
        }
        // 정렬을 꼭 해줘야 함. list에 저장된 값이 무엇인지 모르기 때문에
        Collections.sort(list);
        for (int j : list) {
            System.out.println(j);
        }
    }
}

여기서 중요한 부분은, list를 꼭 sort해줘야 하는 것이다. 왜냐하면, 출력 방식이 오름차순이기 때문이다.

 

정리

코드 자체는 1차원 배열을 사용하는 것이 편하지만, 자료구조를 배우면 효율적인 코드를 짤 수 있다. 수행 시간도 줄일 수 있을 분더러, 메모리를 효율적으로 사용할 수 있다. 물론, 무조건 Collection class를 이용한다고 해서 더 좋다는 것은 아니다.

반응형
반응형

https://www.acmicpc.net/problem/2720

 

2720번: 세탁소 사장 동혁

각 테스트케이스에 대해 필요한 쿼터의 개수, 다임의 개수, 니켈의 개수, 페니의 개수를 공백으로 구분하여 출력한다.

www.acmicpc.net

문제

거스름돈의 액수가 주어지면 리암이 줘야할 쿼터(Quarter, $0.25)의 개수, 다임(Dime, $0.10)의 개수, 니켈(Nickel, $0.05)의 개수, 페니(Penny, $0.01)의 개수를 구하는 프로그램을 작성하시오. 거스름돈은 항상 $5.00 이하이고, 손님이 받는 동전의 개수를 최소로 하려고 한다. 예를 들어, $1.24를 거슬러 주어야 한다면, 손님은 4쿼터, 2다임, 0니켈, 4페니를 받게 된다.

 

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 거스름돈 C를 나타내는 정수 하나로 이루어져 있다. C의 단위는 센트이다. (1달러 = 100센트) (1<=C<=500)

 

출력

각 테스트케이스에 대해 필요한 쿼터의 개수, 다임의 개수, 니켈의 개수, 페니의 개수를 공백으로 구분하여 출력한다.

 

접근 방법

- 우선 Greedy 문제인 것을 직감적으로 알 수 있다.
입력받은 센트를 쿼터(Quarter,$0.25)로 나눴을 때 몫을 따로 저장하고, 나머지는 다시 피제수(나눠지는 수)가 된다.
그 피제수(나눠지는 수)를 다시 다임(Dime, $0.10)으로 나누고, 몫을 따로 저장하고 나머지는 다시 니켈(Nickel, $0.05)로 나눈다. 마지막으로 페니(Penny, $0.01)로 같은 작업을 반복하여  몫을 LinkedList에 저장하고 출력하면 된다.

 

정리

1. 쿼터, 다임, 니켈, 페니를 각각 25, 10, 5, 1 센트 단위로 생각하여 num배열을 하나 만든다. 그리고 몇 번 반복할지 T 값을 받는다.

 

2. 접근 방법에 해당하는 알고리즘을 구현한다.

 

3. Iterator를 사용하여 LinkedList의 원소를 출력한다.

import java.io.*;
import java.util.*;

class Main {
    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);

        int[] num = {25, 10, 5, 1};
        int T = sc.nextInt();

//        // 1. LinkedList를 T 크기 만큼 만든다.
        LinkedList<Integer> arr = new LinkedList<>();

        for (int i = 0; i < T; i++) {
            arr.add(sc.nextInt());
        }

        // 2. for문으로 각 값의 몫과 나머지를 구한다
        for (int i = 0; i < arr.size(); i++) {
            LinkedList<Integer> li = new LinkedList<>();
            for (int j = 0; j < num.length; j++) {
                // 몫 추가
                li.add(arr.get(i) / num[j]);
                // 나머지 처리
                arr.add(i, arr.get(i) % num[j]);
                arr.remove(i + 1);
            }

            Iterator<Integer> it = li.iterator();
            while (it.hasNext()) {
                System.out.print(it.next() + " ");
            }
            System.out.println();
        }
    }
}

 

회고

- 해당 코드에서 핵심은 몫과 나머지를 어떻게 처리하냐의 문제이다. 반복 횟수가 많지는 않은데, ArrayList와 LinkedList 중 어떤 것을 써야 더 효율적일까를 고민해보았고, 물리적으로 비연속적인 LinkedList가 삽입/삭제에 더 유리하기 때문에 LinkedList를 채택했다. 사실 ArrayList를 써도 되지만, 각각의 특징을 공부하고 나니까 간단한 문제에도 이렇게 고민을 하게 되는 것 같다. 

그리고, List형태를 출력할 때 for each문 보다 Iterator를 쓰는게 효율적이라는 것을 알게 되었다. for each문은 Map클래스를 출력할 때 용이하다.

반응형
반응형

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., 스프링 학습 첫 길잡이! 개발 공부의 길을 잃지 않도록 도와드립니다. 📣 확인해주세

www.inflearn.com

해당 내용은 위 무료 강의 내용을 수행하며, 제가 겪은 오류를 어떻게 해결하는지 정리했습니다.


강의 내용 : 섹션1. 프로젝트 환경 설정 - 프로젝트 생성

 

해당 강의에서는 spring boot 2.x.x 버젼을 사용하고 있는데, 나는 3.x.x버젼을 사용하고 있었다. 그래서 java 17 이상의 버젼이 필요했다.

 

우선 강의에 설명해주신 대로 starter.spring.io 에서 프로젝트를 생성하고 Intellij에서 프로젝트를 열었더니 아래와 같은 문구가 나오며 오류가 발생했다.

 

JDK 17 isn't compatible with Gradle 8.1.1. Please fix JAVA_HOME environment variable.

 

이 문제를, 다음과 같은 수행 절차를 통해 해결했다.

1. 환경변수 설정

2. 프로젝트 JDK 설정

 

1. 환경변수 설정

JDK 17이 Gradle 8.1.1과 호환이 안된다는 것이니, 환경변수를 설정하라는 내용이었다. 일단? 내가 알기론 Gradle 8.1.1은 JDK 17과 호환이 되는데, 왜 저런 문구가 뜨지 싶어서 환경 변수 설정을 하려고 봤는데.. 알고보니 JDK 11로 설정되어 있었다. 그래서 17로 다시 바꿔줬다.

 

환경 변수 설정하는 법

- window키 + s

- '고급 시스템 설정 보기' 검색

- 환경 변수 클릭

 

 

 

2. 프로젝트 JDK 17 변경

File -> Project Structure

 

Project SDK에서 자바 17version으로 바꿨다.

 

또한, File -> Settings -> Gradle 검색

Build and run using과 Run tests using을 Gradle에서 Intellij IDEA로 변경했다.

기본 설정값은 Gradle인데, Gradle 공식 홈페이지에서는 Gradle을 수행하는데 있어 오류가 없게 하도록 하기 위해 디폴트 값을 Gradle로 해놨다고 한다. 근데 Gradle로 컴파일 하면 속도가 느리다는 단점이 있어서, Intellij IDEA로 설정했다.

 

 

그리고 Gradle을 다시 빌드하니 오류가 나지 않았고, 해당 강의대로 (아무것도 없는)main 클래스를 실행했을 때 Tomcat이 8080포트로 시작된 것을 확인할 수 있다. 이를 확인하기 위해 localhost:8080으로 접속하면 아래와 같은 오류 페이지가 뜬다. 이로써 셋팅 완료!

 

 

 

반응형
반응형


문제 : gradle version이 달라서, compile, testCompile로 의존성을 설정하는 것이 안될 때.

 

결론 : 

compile은 implementation으로, testCompile은 testImplementation으로 변경하면 된다.

gradle 7.0 부터는 compile과 runtime을 사용하지 않게 되었기 때문이다.

 

https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation

 

The Java Library Plugin

The Java Library plugin expands the capabilities of the Java Plugin (java) by providing specific knowledge about Java libraries. In particular, a Java library exposes an API to consumers (i.e., other projects using the Java or the Java Library plugin). All

docs.gradle.org

The compile and runtime configurations have been removed with Gradle 7.0. Please refer to the upgrade guide how to migrate to implementation and api configurations`. - 출처 : gradle 공식 홈페이지 -

 

 

buildscript {
    ext {
        springBootVersion = '2.1.9.RELEASE'
    }
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group 'com.jojoldu.book'
version '1.0.4-SNAPSHOT-'+new Date().format("yyyyMMddHHmmss")
sourceCompatibility = 1.8

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile("org.springframework.security:spring-security-test")
}

해당 책은 gradle 4.10.2 version을 사용하고 있어서, 의존성을 추가할 때 compile, testCompile을 사용했다. 하지만, 지금은 책이 출간한지 5년 정도가 지났기에.. 나는 gradle 7.1 version을 사용하고 있었다. 그래서 위와 같은 코드를 작성했을 때 오류가 났다.

 

앞서 말한 것처럼, compile을 implementation으로, testCompile을 testImpementation으로 변경하니 빌드가 성공됐다.

 

buildscript {
    ext {
        springBootVersion = '2.1.9.RELEASE'
    }
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group 'com.jojoldu.book'
version '1.0.4-SNAPSHOT-'+new Date().format("yyyyMMddHHmmss")
sourceCompatibility = 1.8

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
    testImplementation("org.springframework.security:spring-security-test")
}

 

여기서 의문점... 이렇게 gradle 7.1 버젼에서 빌드 하긴 했는데, 나중에 다시 다운그레이드 했을 때는 implementation이 안먹힐 줄 알았는데 그대로 적용이 됐다... 왜지..??

 

 

 

compile, testCompile에 대한 정보 출처

https://velog.io/@g0709-19/Gradle-Could-not-find-method-compile-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95

 

Gradle Could not find method compile() 해결 방법

gradle 7.0 부터 compile 명령은 삭제되었습니다.

velog.io

 

 

 

 

반응형
반응형

자바를 공부하다 보면 헷갈리는 용어가 많은데, 특히 오버로딩(Overloading)과 오버라이딩(Overriding)이 비슷해서 많이 헷갈린다. 그런데, 사실 둘은 아무 관계 없는 내용이다. 둘의 차이점을 알아보자.

 

  오버로딩(Overloading) 오버라이딩(Overriding)
접근 제어 달라도 됨 같음
반환형 달라도 됨 같음
메서드 이름 같음 같음
매개변수 달라도 됨 같음

 

1. 오버로딩(Overloading)

같은 클래스 내에서 매소드를 확장하기 위한 것. 메소드 명은 같지만, 매개 변수, 반환형 등을 다르게 하여 편리하게 사용 가능하다.

  • 메서드 이름이 같다.
  • 매개 변수, 반환형(return)은 달라도 된다. 
  • 같은 클래스 내에 선언 되어야 한다.
  • 만약 매개 변수의 개수가 같다면 자료형이 달라야 하고, 자료형이 모두 같다면 매개 변수의 개수를 다르게 해야 한다.

코드 예시를 통해 개념을 익혀보자.

class Hello {
    void overL() {
        System.out.println("오버로딩을 위한 메서드");
    }

    void overL(String str){
        System.out.println("매개 변수 타입이 String 이고, 값은 " + str);
    }

    void overL(int k){
        System.out.println("매개 변수 타입이 int 이고, 값은 " + k);
    }

    int overL(int x, int y){
        System.out.println("반환형이 다른 메서드");
        return x;
    }
}


public class HelloJava {
    public static void main(String[] args) {

        Hello ov = new Hello();

        ov.overL();
        ov.overL("오버로딩 예제");
        int num = ov.overL(5, 6);
        System.out.println(num);

    }
}

 

2. 오버라이딩(Overriding)

부모 클래스의 메서드를 자식 클래스에서 메서드를 '재정의'하는 것이다. 

  • 메서드 명, 매개 변수, 반환형, 접근 제어자가 모두 같다.
  • 상속 받은 부모 클래스의 메서드를 재정의 하는 것이다. 다른 클래스의 메서드를 재정의 하는 것이 아니다!
class Animal {
    public void makeSound() {
        System.out.println("동물이 소리를 내고 있습니다.");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("강아지가 멍멍 소리를 내고 있습니다.");
    }
}

public class HelloJava {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = new Dog();

        animal.makeSound(); // "동물이 소리를 내고 있습니다." 출력
        dog.makeSound();    // "강아지가 멍멍 소리를 내고 있습니다." 출력

    }
}

 

반응형
반응형

추상클래스란?

1. 추상 메소드와 완성된 메소드로 구성되어 있는 클래스.
 
2. 추상 메소드(Abstract Method)선언부만 존재하며, 구현부 {}는 존재하지 않는다.
 
3. 만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면, 상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다.
 
4. 추상 클래스를 상속받은 클래스는 추상 클래스에 있는 추상 메소드를 구현해줘야한다. 단, 상속 받은 클래스가 추상 클래스일 경우에는 모든 추상 메소드를 구현하지 않아도 된다.

우선 첫 번쨰와 두 번째 정의를 살펴보자.

 

1. 추상 메소드와 완성된 메소드로 구성되어 있는 클래스.

2. 추상 메소드(Abstract Method)는 선언부만 존재하며구현부 {}는 존재하지 않는다.

초록색 네모 안에는 class 앞에 abstract를 사용하여 추상 클래스임을 확인할 수 있다.

빨간색 네모 안에 있는 abstract void move(int x, int y);는 여타 메소드와는 다르게 구현부 {}, 중괄호로 되어 있는 부분이 없다. 이런 메소드를 추상 메소드라고 불리며, 껍데기만 있다고 표현할 수 있다.

검은 네모 안에 있는 메소드는 흔히 볼 수 있는 메소드이다. 선언부에 void stop()이 있고, 구현부에는 값을 출력하는 것을 보이고 있다.

이처럼 추상 클래스는 클래스 내에 추상 메소드, 일반 메소드가 모두 존재할 수 있다. 하지만, 인터페이스는 무조건 추상 메소드만 있어야 한다는 것이 추상 클래스와의 차이점이다.

 

3. 만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다.

abstract class Unit {       // 추상 클래스에는 일반 메서드도 포함. 인터페이스는 무조건 추상메서드
    int x, y;
    abstract void move(int x, int y);
    void stop() {/* 현재 위치에 정지 */}
}

class Marine extends Unit {
    void move(int x, int y){
        System.out.println("Marine[ x = " + x + ", y = " + y + "]");
    }
}

class Tank extends Unit {
    void move(int x, int y){
        System.out.println("Tank[ x = " + x + ", y = " + y + "]");
    }
}   

class Dropship extends Unit {
    void move(int x, int y) {
        System.out.println("Dropship[ x = " + x + ", y = " + y + "]");
    }
}

public class Abstract3 {
    public static void main(String args[]){
//      Unit[] group = {new Marine(), new Dropship(), new Tank()}; 아래 세 줄을 한 줄로 줄인 것   // 추상 클래스 객체를 만드는 건 불가능. 왜냐면 추상 클래스에는 추상 메서드가 있을 수 있기 때문. 그래서 상속받은 클래스 형으로 객체를 생성해야 함.
        Unit[] group = new Unit[3];
        group[0] = new Marine();
        group[1] = new Dropship();
        group[2] = new Tank();
    
        group[0].move(100, 200);
        group[1].move(100, 200);
        group[2].move(100, 200);

    }
}

 

우측이 추상 클래스, 좌측이 추상 클래스를 상속받은 Marine, Tank, Dropship 클래스

Unit 이라는 추상 클래스를 상속 받은 Marine, Tank, Dropship 클래스들은 추상 메서드인 abstract void move(int x, int y);를 구현(완성)하고 있는 것을 확인할 수 있다. 만약 Unit 추상 클래스를 상속받은 일반 클래스에서, move 메서드를 구현하지 않았다면 컴파일러에서 에러를 발견하여 빨간 줄이 뜨는 걸 볼 수 있다. 이렇게 추상 매서드를 구현해야 main에서 Unit 객체를 생성할 수 있다.

 

이렇듯, 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만들 수 있다.

 

(참고, Marine, Tank, Dropship 객체를 생성하되 참조변수는 Unit 으로 선언할 수 있다. 왜냐하면 상속 받았기 때문!

 

ex) Unit[] group = new Unit[3]; 

Unit[] group = new Marine[3];

Unit[] group = new Tank[3];

Unit[] group = new Dropship[3] ;

 

하지만 Marine 객체를 선언하면 Marine 클래스 내에 있는 메소드와 상속 받은 Unit 클래스 내에 있는 메소드만 사용 가능하다. 나머지도 동일!)

 

4. 추상 클래스를 상속받은 클래스는 추상 클래스에 있는 추상 메소드를 구현해줘야한다. 단, 상속 받은 클래스가 추상 클래스일 경우에는 모든 추상 메소드를 구현하지 않아도 된다.

 

이게 무슨 뜻인지 아래 코드를 보며 이해해보자.

 

좌측이 추상 클래스, 우측이 Marine 클래스

추상 클래스 Unit에는 세 가지의 메서드가 있다.

abstact void move, abstract void fly, void stop.

 

<만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다>라는 3번의 정의에 따르면,  현재 Marine 클래스에는 move 메서드는 구현했지만 fly 메서드는 구현하지 않았다. 그래서 빨간 줄이 나오는 것을 볼 수 있다. 

 

하지만, 여기서 Marine 클래스를 추상 클래스로 선언한다면, 굳이 모든 추상 메서드를 구현할 필요가 없어진다.

반응형
반응형

 

https://school.programmers.co.kr/learn/courses/30/lessons/181892

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 문제 설명

정수 리스트 num_list와 정수 n이 주어질 때, n 번째 원소부터 마지막 원소까지의 모든 원소를 담은 리스트를 return하도록 solution 함수를 완성해주세요.

 

 

2. 접근 방법

  1. answer 배열의 크기가 num_list.length - n + 1 것을 파악한다.
  2. num_list[n-1] 부터 num_list[n], num_list[n+1]의 수를 각각 answer[0], answer[1], answer[2] 이렇게 차례로 넣을 for 문을 만든다.

 

3. 코드

class Solution {
    public int[] solution(int[] num_list, int n) {
        int[] answer = new int[num_list.length - n + 1];
        
        for(int i = 0; i < answer.length; i++){
            answer[i] = num_list[n-1];
            n++;	// n을 1씩 증가시켜서 anser[i+1]에는 num_list[n]이 오도록 한다
        }
        return answer;
    }
}
반응형
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/181928

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 문제 설명

정수가 담긴 리스트 num_list가 주어집니다. num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 함수를 완성해주세요.

 

2. 접근 방법

1) 일단 if문으로 짝수, 홀수 나눠서 새로운 배열에 저장한다. 이떄, num_list에 있는 int 형을 String으로 변환하여 각각 짝수 문자열(even)과 홀수 문자열(odd)에 저장.

 

2) String으로 저장된 값을 Integer.parseInt()로 형변환 하여 두 배열의 합을 구한다.

 

class Solution {
    public int solution(int[] num_list) {
        int answer = 0;
        
        String even = "";
        String odd = "";
        
        for(int i = 0; i < num_list.length; i++){
            if(num_list[i] % 2 == 0){
                even = even + Integer.toString(num_list[i]);	//짝수 입력
            }
            else{
                odd = odd + Integer.toString(num_list[i]);		// 홀수 입력
            }
            
        }
        answer = Integer.parseInt(even) + Integer.parseInt(odd);
        return answer;
    }
}

 

3. 회고

처음에는 Integer 객체를 쓰지 않고 구현하려고 했다.  근데 너무 복잡하게 생각했던 나머지, 그냥 String으로 변환해서 풀기로 했다. 굳이 10의 제곱수를 만들기 위해 2중 for문을 안 만들어도 됐었는데.. 역시 알고리즘 풀 때는 간단하게 생각해야 하는 것 같다.

 

반응형

+ Recent posts