728x90

1978번 소수 찾기


내가 떠올린 풀이 해설

소수를 찾는 기본 문제이다. 소수를 찾기 위해 아래의 코드를 추가시켰다.

for(int j = 2; j < arr[i]; j++) {
   if(arr[i] % j == 0) {
      isPrime = false;
      break;
   }

위의 코드 if문이 실행되면 소수가 아니므로 isPrime에 false를 하고 break로 빠져나왔다. 마지막에 만약 isPrime이면 cnt를 늘려주는 식으로 소수의 개수를 구했다.


정확한 풀이

import java.util.*;
public class Baek1978 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n  = sc.nextInt();
		int[] arr = new int[n];
		for(int i = 0 ; i < n; i++) {
			arr[i] = sc.nextInt();
		}
		int cnt = 0;
		for(int i = 0; i < n; i++) {
			boolean isPrime = true;
			if(arr[i] == 1) {
				continue;
			}
			for(int j = 2; j < arr[i]; j++) {
				if(arr[i] % j == 0) {
					isPrime = false;
					break;
				}
			}
			if(isPrime) {
				cnt++;
			}
		}
		System.out.println(cnt);
	}
}

1654번 랜선 자르기


내가 떠올린 풀이 해설

변수의 크기를 고려해서 변수를 선언해야 된다. 그렇지 않으면 답이 틀렸다고 나온다. 이 문제 또한 기본 이분 탐색 문제이다. 렌선의 최소 길이인 1로 start를 잡고 end는 렌선 배열의 최대 값을 선언해준다.  while문에서 start가 end보다 작거나 같을 때까지 반복한다. while문 안에서 이분 탐색으로 총 만들 수 있는 개수를 구해주면 된다.


정확한 풀이

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

public class Baek1654 {

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int k = Integer.parseInt(st.nextToken());
		long n = Long.parseLong(st.nextToken());
		
		long[] arr = new long[k];
		for(int i = 0; i < k; i++) {
			arr[i] = Long.parseLong(br.readLine());
		}
		Arrays.sort(arr);
		
		long start = 1;
		long end = arr[k - 1];
		long mid = 0;
		
		while(start <= end) {
			mid = (start + end) / 2;
			int sum = 0;
			for(int i = 0; i < k; i++) {
				sum += arr[i] / mid;
			}
			if(sum < n) {
				end = mid - 1;
			}
			else {
				start = mid + 1;
			}
		}
		System.out.println(end);
	}
}

오늘의 회고

기본 문제들이라 문제를 해결하는데 어려움은 없었습니다.

제가 이번에 스터디에 참여하게 되었습니다. 주제를 잡고 스터디하는 것이 아니라 모여서 각자 코딩하고 어떤 공부를 하는지 이야기하는 모임입니다. 일요일에 처음 참여하게 되었는데 앞으로도 다른 스터디나 스터디를 꾸준히 할 생각입니다. 스터디에 참여하게 된 이유는 따로 같은 분야에 계신 선배님들을 만날 기회가 없고 스터디 카페에 박혀있어 우울해지는 것 같아 참여하게 되었습니다. 스터디에 계신 분들도 다 저보다 연차가 높은 선배님들이라 열심히 배우겠습니다. 내일은 프로그래머스 중간고사가 있어서 중간고사 시험을 보고 오겠습니다. 중간고사 문제는 외부로 유출이 안돼서 블로그에 작성은 하지 못할 것 같습니다.

728x90
728x90

컬렉션

여러 객체(데이터)를 모아놓은 것을 의미

 

프레임웍

표준화 정형화된 체계적인 프로그래밍 방식

 

컬렉션 프레임웍

컬렉션(다수의 객체)을 다루기 위한 표준화된 프로그래밍 방식

컬렉션을 쉽고 편리하게 다룰 수 있는 다양한 클래스를 제공

java.util 패키지에 포함

 

1. List

순서가 있는 데이터의 집합. 데이터의 중복을 허용한다.

구현 클래스 : ArrayList, LinkedList, Stack, Vector 등

2. Set

순서를 유지하지 않는 데이터의 집합. 데이터의 중복을 허용하지 않는다.

구현 클래스 : HashSet, TreeSet 등

3. Map

키와 값의 쌍으로 이루어진 데이터의 집합

순서는 유지되지 않으며, 키는 중복을 허용하지 않고, 값은 중복을 허용한다.

구현 클래스 : HashMap, TreeMap, HashTable, Propertise 등

 

ArrayList

ArrayList는 기존의 Vector를 개선한 것으로 구현원리와 기능적으로 동일

ArrayList와 달리 Vector는 자체적으로 동기화 처리가 되어있다.

List인터페이스를 구현하므로, 저장순서가 유지되고 중복을 허용한다.

데이터의 저장공간으로 배열을 사용한다.

 

ArrayList에 저장된 객체의 삭제과정

  1. 삭제할 데이터 아래의 데이터를 한 칸씩 위로 복사해서 삭제할 데이터를 덮어쓴다.
  2. 데이터가 모두 한 칸씩 이동했으므로 마지막 데이터는 null로 변경한다.
  3. 데이터가 삭제되어 데이터의 개수가 줄었으므로 size를 감소시킨다.

배열의 장점

배열은 구조가 간단하고 데이터를 읽는 데 걸리는 시간이 짧다

배열의 단점

크기를 변경할 수 없다. 크기를 변경해야 하는 경우 새로운 배열을 생성 후 데이터를 복사해야 함

비순차적인 데이터의 추가, 삭제에 시간이 많이 걸린다.

 

LinkedList 

배열과 달리 LinkedList는 불연속적으로 존재하는 데이터를 연결

데이터의 삭제 : 단  한 번의 참조 변경만으로 가능

데이터의 추가 : 한 번의 Node객체 생성과 두 번의 참조 변경만으로 가능

순차적으로 데이터 추가/삭제 : ArrayList가 빠름

비순차적으로 데이터 추가/삭제 : LinkedList가 빠름

접근 시간 : ArrayList가 빠름

 

Comparable : 기본 정렬 기준을 구현하는데 사용

Comparator : 기본 정렬기준 외의 다른 기준으로 정렬하고자 할 때 사용

compare()와 compareTo()는 두 개체의 비교 결과를 반환하도록 작성 

 

HashSet

set인터페이스를 구현한 대표적인 컬렉션 클래스

순서를 유지하려면, LinkedHashSet클래스를 사용하면 된다.

 

TreeSet

범위 검색과 정렬에 유리한 컬렉션 클래스

HashSet보다 데이터 추가, 삭제에 시간이 더 걸림

728x90
728x90

87번 2 x n 타일링


내가 떠올린 풀이 해설

크기가 2 x 1일 때부터 2 x 2... 하나씩 높여가면서 경우의 수를 구하면 규칙이 나온다. 그 규칙을 이용해서 점화식을 구하면 되는 문제이다. 점화식은 arr [n] = arr[n - 1] + arr[n - 2]이다. arr배열을 채울 때마다 10,007으로 % 연산을 수행해야 한다. 


정확한 풀이

import java.util.*;
public class Baek11726 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		long[] arr = new long[n + 1];
		arr[1] = 1;
		arr[2] = 2;
		int mod = 10007;
		for(int i = 3; i <= n; i++) {
			arr[i] = (arr[i - 1] + arr[i - 2]) % mod;
		}
		System.out.println(arr[n]);
	}
}

88번 쉬운 계단 수


내가 떠올린 풀이 해설

n번째 길이에서 5로 끝나는 계단 수가 있었을 때 이 계단 수의 n - 1의 자리에 올 수 있는 수는 1 차이가 나는 4와 6이다. 이를 이용해 문제를 풀겠다. arr[n][h] : 길이가 n인 계단에서 h 높이로 종료되는 계단 수를 만들 수 있는 경우의 수이다. n에서 계단 높이가 0일 때 계단 수가 되려면 n - 1에서는 높이가 1이어야 한다. n에서 계단 높이가 9일 때 계단 수가 되려면 n - 1 에서는 높이가 8이어야 한다. 나머지는 가운데 계단이므로 h + 1, h - 1 양쪽에서 계단 수를 만들 수 있다. 

 

높이에 따른 점화식

  •  arr[i][h] = arr[i - 1][h + 1] // h = 0
  • arr[i][h] = arr[i - 1][h - 1] // h = 9
  • arr[i][h] = arr[i + 1][h - 1] + arr[i - 1][h - 1] // h = 1 ~ 8

arr배열의 값을 초기화한다. 각 높이에서 길이가 1인 계단 수는 모두 1가지이므로 1로 초기화한다. 단, 0으로 시작될 수 없으므로 이때는 0으로 초기화한다. arr 배열을 채울 때마다 1000000000으로 % 연산을 수행한다. arr[n][0] ~ arr[n][9]의 모든 값을 더한 값을 출력한다 n = 2일 때 각 자릿수의 값을 모두 더하면 n = 2의 길이에서 만들 수 있는 모든 계단 수의 경우의 수를 출력할 수 있다.


정확한 풀이

import java.util.Scanner;

public class Baek10844 {

	public static void main(String[] args) {
		long mod = 1000000000;
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		long[][] arr = new long[n + 1][11];
		for(int i = 1; i <= 9; i++) {
			arr[1][i] = 1;
		}
		for(int i = 2; i <= n; i++) {
			arr[i][0] = arr[i - 1][1];
			arr[i][9] = arr[i - 1][8];
			for(int j = 1; j <= 8; j++) {
				arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j + 1]) % mod;
			}
		}
		long sum = 0;
		for(int i = 0; i < 10; i++) {
			sum = (sum + arr[n][i]) % mod;
		}
		System.out.println(sum);
	}

}

오늘의 회고

오늘은 DP문제 2문제를 풀었습니다. 첫 번째 문제는 난이도가 높지 않은 문제였고, 두 번째 문제는 문제를 이해하는데 시간이 많이 걸렸습니다. 프로그래머스 교육도 진행 중이라 앞의 개념에 대해 까먹을 것 같습니다. 이제는 교육도 듣고 앞에 문제 개념도 복습하고 그 개념에 대한 문제를 푸는 식으로 공부를 진행해야 될 것 같습니다. 하면 할수록 저는 알고리즘이 어려운 것 같습니다. 알고리즘 잘하고 싶다. 꾸준히 공부하겠습니다.

728x90
728x90

연결된 예외

한 예외가 다른 예외를 발생시킬 수 있다.

예외 A가 예외 B를 발생시키면, A는 B의 원인 예외

Throwable initCause(Throwable cause) // 지정한 예외를 원인 예외로 등록
Throwable getCause() // 원인 예외를 반환

 

사용하는 이유

  1. 여러 예외를 하나로 묶어서 다루기 위해서
  2. checked 예외를 unchecked 예외로 변경하려고 할 때

hashcode()

객체의 해시 코드를 반환하는 메서드

Object클래스의 hashCode()는 객체의 주소를 int로 변환해서 반환

equals()를 오버 라이딩하면, hashCode()도 오버 라이딩해야 한다.

equals()의 결과가 true인 두 객체의 해시코드는 같아야 하기 때문

 

toString()

객체를 문자열으로 변환하기 위한 메서드

 

String(char[] value) 메서드

주어진 문자열을 갖는 String 인스턴스를 생성한다.(문자 배열을 문자열로 바꿔준다.)

char c[] = {'H', 'E', 'L', 'L', 'O'};
String s = new String(c);
==================================
s = "HELLO"

int compareTo(String str)

문자열과 사전순서로 비교한다. 같으면 0을, 사전 순으로 이전이면 음수를, 이후면 양수를 반환

int i = "aaa".compareTo("aaa");
int i2 = "aaa".compareTo("bbb");
int i3 = "bbb".compareTo("aaa");
================================
i = 0, i2 = -1, i3 = 1

boolean contains(charSequence s)

지정된 문자열이 포함되어 있는지 검사

String s = "abcdefg";
boolean b = s.contains("bc");
=============================
b = true

boolean endsWith(String suffix)

지정된 문자열(suffix)로 끝나는지 검사한다.

String file = "Hello.txt";
boolean b = file.endsWith("txt");
=================================
b = true

boolean equalsIgnoreCase(String str)

문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교한다.

String s = "Hello";
boolean b = s.equalsIgnoreCase("HELLO");
boolean b2 = s.equalsIgnoreCase("heLLO");
=========================================
b = true, b2 = true

int indexOf(int ch), int indexOf(int ch, int pos)

주어진 문자(ch)가 문자열에 존재하는지 확인하여 위치(index)를 알려준다. 못 찾으면 -1을 반환한다.

 

String s = "Hello";
int idx = s.indexOf('o');
int idx2 = s.indexOf('k');
int idx3 = s.indexOf('e', 0);
int idx4 = s.indexOf('e', 2);
=========================================
idx = 4, idx2 = -1, idx3 = 1, idx4 = -1

String[] split(String regex), String[] split(String regex, int limit) 

문자열을 지정된 분리자(regex)로 나누어 문자열 배열에 담아 반환한다.

String animal = "dog,cat,bear");
String[] arr = animal.split(",");
String[] arr2 = animal.split(",", 2);
===============================================
arr[0] = "dog", arr[1] = "cat", arr[2] = "bear"
arr2[0] = "dog", arr2[1] = "cat,bear"

String substring(int begin) String substring(int begin, int end)

주어진 시작위치(begin)부터 끝 위치(end) 범위에 포함된 문자열을 얻는다. 이때 시작 위치의 문자는 범위에 포함되지만, 끝 위치의 문자는 포함되지 않는다.

String s = "java.lang.Object";
String c = s.substring(10);
String p = s.subString(5, 9);
=================================
c = "Object", p = "lang"

String trim()

문자열의 왼쪽 끝과 오른쪽 끝에 있는 공백을 없앤 결과를 반환한다. 이 때 문자열 중간의 공백은 제거되지 않는다.

String s = "  Hello World  ";
String s1 = s.trim();
===============================
s1 = "Hello World"

join()

여러 문자열 사이에 구분자를 넣어서 결합한다.

String animal = "dog,cat,bear";
String[] arr = animal.split(",");
String str = String.join("-", arr);
System.out.println(str);
====================================
str = dog-cat-bear

StringBuffer 클래스

String 처럼 문자형 배열(char[])을 내부적으로 가지고 있다.

그러나 String과 달리 내용을 변경할 수 있다.

append()는 지정된 내용을 StringBuffer에 추가 후, StringBuffer의 참조를 반환

StringBuffer는 equals()가 오버라이딩되어있지 않다.

StringBuffer를 String으로 변환 후에 equals()로 비교해야 한다.

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb == sb2) // false
System.out.println(sb.equals(sb2)) // false
================================================
String s = sb.toString();
String s2 = sb.toString();
System.out.println(s.equals(s2)) // true

StringBuilder

StringBuilder는 동기화되어 있다. 멀티 스레드에 안전(thread-safe)

멀티 쓰레드 프로그램이 아닌 경우, 동기화는 불필요한 성능 저하 이럴 땐 StringBuffer 대신 StringBuilder를 사용하면 성능 향상

 

static int abs(int f)

주어진 값의 절댓값을 반환한다.

int i = Math.abs(-10);
======================
i = 10

static double ceil(double a)

주어진 값을 올림하여 반환한다.

double d = Math.ceil(10.1);
============================
d = 11.0

static double floor(double a)

주어진 값을 버림하여 반환한다.

double d = Math.floor(10.8);
double d2 = Math.floor(-10.8);
===============================
d = 10.0, d2 = -11.0

static long round(float a)

소수점 첫째자리에서 반올림한 정수 값(long)을 반환한다. 두 정수중 가운데 있는 값은 항상 큰 정수를 반환

 

래퍼(wrapper) 클래스

8개의 기본형을 객체로 다뤄야 할 때 사용하는 클래스

기본형 첫 글자를 대문자로 바꾸면 됨

래퍼 클래스는 모두 equals()가 오버 라이딩되어 있어서 주소가 아닌 객체 값을 비교한다.

 

728x90
728x90

인터페이스를 이용한 다형성

인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능

인터페이스를 메서드의 리턴 타입으로 지정할 수 있다.

 

인터페이스의 장점

  • 두 대상(객체)간의 연결, 대화, 소통을 돕는 중간 역할을 한다.
  • 선언(설계)과 구현을 분리시킬 수 있게 한다.
  • 인터페이스 덕분에 B가 변경되어도 A는 안 바꿀 수 있게 된다.
  • 개발 시간을 단축할 수 있다.
  • 변경에 유리한 유연한 설계가 가능하다.
  • 표준화가 가능하다.
  • 서로 관계없는 클래스들을 관계를 맺어줄 수 있다.

디폴트 메서드와 static메서드

인터페이스에 디폴트 메서드, static 메서드 추가 가능(jdk 1.8부터)

인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어려움 -> 디폴트 메서드 생성

디폴트 메서드는 인스턴스 메서드(인터페이스 원칙 위반)

interface MyInterface {
	void method();
    void newMethod(); // 추상 메서드
}

해결책
interface MyInterface {
	void method();
    default void newMethod() {}
}

디폴트 메서드가 기존의 메서드와 충돌할 때의 해결책

1. 여러 인터페이스의 디폴트 메서드 간의 충돌

인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.

2. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌

조상클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

 

내부 클래스

클래스 안에 클래스

 

내부 클래스의 장점

내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.

코드의 복잡성을 줄일 수 있다.(캡슐화)

내부 클래스의 제어자는 변수에 사용 가능한 제어자와 동일

 

프로그램 오류

컴파일 에러 : 컴파일 할 때 발생하는 오류

런타임 에러 : 실행 할 때 발생하는 오류

논리적 에러 : 작성 의도와 다르게 동작

 

Java 런타임 에러

에러 : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류

예외 : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

 

예외처리의 정의와 목적

정의 : 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것

목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것

 

Exception 클래스 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외

RuntimeException 클래스 : 프로그래머의 실수로 발생하는 예외

 

try-catch 문에서의 흐름

1. try블럭 내에서 예외가 발생한 경우

  1. 발생한 예외와 일치하는 catch 블록이 있는지 확인한다.
  2. 일치하는 catch 블럭을 찾게 되면 그 catch 블록 내의 문장들을 수행하고 전체 try - catch 문을 빠져나가서 그다음 문장을 계속해서 수행한다. 만일 일치하는 catch 블록을 찾지 못하면 예외는 처리되지 못한다.

2. try 블럭 내에서 예외가 발생하지 않은 경우

  1. catch 블럭을 거치지 않고 전체 try-catch 문을 빠져나가서 수행을 계속한다.

printStackTrace() : 예외 발생 당시의 호출 스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.

getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.

 

checked 예외 : 컴파일러가 예외 처리 여부를 체크(예외 처리 필수 : Exception)

unchecked 예외 : 컴파일러가 예외 처리 여부를 체크 안 함(예외 처리 선택 : RuntimeException) 

 

예외를 처리하는 방법

try-catch문, 예외 선언하기

 

예외 선언

메서드가 호출시 발생 가능한 예외를 호출하는 쪽에 알리는 것 

 

finally 블럭

예외 발생 여부와 관계없이 수행되어야 하는 코드를 넣는다.

try-catch 문 제일 마지막에 위치해야 한다.

 

사용자 정의 예외 만들기

우리가 직접 예외 클래스를 정의할 수 있다.

조상은 Exception과 RuntimeException 중에서 선택

 

 

728x90
728x90

step 1 - 2. 가장 큰 수

 


내가 떠올린 풀이 해설

처음에 문제를 보았을 때 투 포인터로 전체를 탐색하면서 문자를 연결해서 숫자 형식으로 바꿔서 max값을 구해서 다시 String으로 바꿔서 출력을 하려고 했는데 실패했다. int형 배열을 String 배열로 바꾸고 Array.sort를 이용해서 정렬을 한다. 만약 전부 0이면 0000으로 나와서 0으로 된 배열만 예외 처리를 해준다.


정확한 풀이

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

class Solution {
    public String solution(int[] numbers) {
        String answer = "";
        String[] str = new String[numbers.length];
        for(int i = 0; i < numbers.length; i++) {
            str[i] = String.valueOf(numbers[i]);
        }
        Arrays.sort(str, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return (b + a).compareTo(a + b);
            }
        });
        if(str[0].equals("0")) {
            return "0";
        }
        else {
            for(int i = 0; i < str.length; i++) {
                answer += str[i];
            }
        }
        return answer;
    }
}

step 1 - 3. 예산


내가 떠올린 풀이

이분 탐색으로 해결하면 되는 문제였다. 근데 이분탐색을 푸는데 갑자기 머릿속이 꼬여서 엄청 헤매면서 풀었다. 정답도 100점 만점에 90점이다.


정확한 풀이

import java.util.*;
class Solution {
    public int solution(int[] budgets, int M) {
       int answer = 0;
        int sum = 0;
        Arrays.sort(budgets);
        for(int i = 0; i < budgets.length; i++) {
            sum += budgets[i];
        }
        int max = 0;
        if(sum >= M) {
        	int start = budgets[0];
            int end = budgets[budgets.length - 1];
            sum = 0;
            while(start <= end) {
                int midv = (start + end) / 2;
                sum = 0;
               //midv = 119 124 127
                for(int i = 0; i < budgets.length; i++) {
                    if(midv > budgets[i]) {
                        sum += budgets[i];
                    }
                    else {
                        sum += midv;
                    }
                }
                if(sum > M) {
                    end = midv - 1;  //end 129 
                }
                else {
                	start = midv + 1;
                	answer = midv;
                }  
            }
        }
        else {
            answer = budgets[budgets.length - 1];
        }
        return answer;
    }
}

오늘의 회고

오늘 문제를 풀면서 너무 헤맷습니다. 공부를 좀 더 열심히 해야 될 것 같습니다. 자신감이 떨어진 하루입니다.ㅠㅠ 좀 더 분발해서 공부하겠습니다. 중간고사도 있는데 중간고사 때 많이 못 풀 것 같은 느낌이.... 열심히 하겠습니다.

728x90
728x90

제어자

클래스와 클래스의 맴버(맴버 변수, 메서드)에 부가적인 의미 부여

  • 접근 제어자 : public, default, protected, private 
  • 그 외 : static, final, abstract, native, transient, 등

final

  • 클래스 : 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다. 그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
  • 메서드 : 변경될 수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
  • 맴버변수, 지역변수 : 변수 앞에 final이 붙으면, 값을 변경할 수 없는  상수가 된다.

abstract

  • 클래스 : 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.
  • 메서드 : 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다.

접근 제어자

  • private : 같은 클래스 내에서만 접근이 가능하다.
  • default : 같은 패키지 내에서만 접근이 가능하다.
  • protected : 같은 패키지 내에서 그리고 다른 패키지의 자손 클래스에서 접근이 가능하다.
  • public : 접근 제한이 전혀 없다.

캡슐화와 접근 제어자

접근 제어자를 사용하는 이유 

  • 외부로부터 데이터를 보호하기 위해
  • 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서

다형성

  • 여러가지 형태를 가질 수 있는 능력
  • 조상 타입 참조 변수로 자손 타입 객체를 다루는 것
  • 자손 타입의 참조 변수로 조상 타입의 객체를 가리킬 수 없다.

참조변수의 형변환

  • 사용할 수 있는 맴버의 개수를 조절하는 것
  • 조상 자손 관계의 참조변수는 서로 형변환 가능

instanceof 연산자

  • 참조변수의 형변환 가능여부 확인에 사용. 가능하면 true 반환
  • 형변환 전에 반드시 instanceof로 확인해야 함

매개변수의 다형성

참조형 매개변수는 메서드 호출 시, 자신과 같은 타입 또는 자손 타입의 인스턴스를 넘겨줄 수  있다.

 

추상 클래스

  • 미완성 설계도, 미완성 메서드를 갖고 있는 클래스
  • 다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가
  • 상속을 통해 추상 메서드를 완성해야 인스턴스 생성 가능

추상 메서드

  • 미완성 메서드. 구현부 {} 없는 메서드
  • 꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우

추상 클래스의 작성

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

추상화된 코드는 구체화된 코드보다 유연하다. 변경에 유리

 

인터페이스

  • 추상 메서드의 집합
  • 구현된 것이 하나도 없는 설계도, 껍데기(모든 맴버가 public)
  • 인터페이스의 조상은 인터페이스만 가능(Object가 최고 조상은 아님)
  • 다중 상속이 가능 

인터페이스의 구현

  • 인터페이스에 정의된 추상 메서드를 완성하는 것
  • 일부만 구현하는 경우 클래스 앞에 abstract를 붙여야 한다.
728x90
728x90

85번 퇴사


내가 떠올린 풀이 해설

max[i] : i번째 날부터 퇴사날까지 벌 수 있는 최대 수입

max[i] = max[i] + 1  : 오늘 시작되는 상담을 했을 때 퇴사일까지 끝나지 않는 경우

max[i] = Math.max(max[i + 1], max[i + day[i]] + pl[i]) : 오늘 시작되는 상담을 했을 때 퇴사일 안에 끝나는 경우

if(i + day[i] > n + 1) : i번째 상담을 퇴사일까지 끝낼 수 없을 때


정확한 풀이

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

public class Baek14501 {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		int[] max = new int[n + 2];
		int[] day = new int[n + 1];
		int[] pl = new int[n + 1];
		
		for(int i = 1; i <= n; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			day[i] = Integer.parseInt(st.nextToken());
			pl[i] = Integer.parseInt(st.nextToken());
		}
		for(int i = n; i > 0; i--) {
			if(i + day[i] > n + 1) {
				max[i] = max[i + 1];
			}
			else {
				max[i] = Math.max(max[i + 1], pl[i] + max[i + day[i]]);
			}
		}
		System.out.println(max[1]);
	}
}

86번 이친수


내가 떠올린 풀이 해설

d[i][0] : i 길이에서 끝이 0으로 끝나는 이친수의 개수 = d[i - 1][1] + d[i - 1][0];

d[i][1] : i 길이에서 끝이 1로 끝나는 이친수의 개수 = d[i - 1][0];


정확한 풀이

package DoitCodingTest;
import java.io.*;
import java.util.*;
public class Baek2193 {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		long[][] d = new long[n + 1][2];
		d[1][1] = 1;
		d[1][0] = 0;
		for(int i = 2; i <= n; i++) {
			d[i][0] = d[i - 1][1] + d[i - 1][0];
			d[i][1] = d[i - 1][0];
		}
		System.out.println(d[n][0] + d[n][1]);
	}

}

오늘의 회고

DP에서 점화식을 잘 못세우겠습니다. 아직 많이 부족하고 많은 연습이 필요할 것 같습니다. 포기하지 않고 끝까지 최선을 다해보겠습니다.

728x90

+ Recent posts