그리고 노드번호와 함께 최장 거리를 priority_queue에 삽입하며 죄장 거리가 작은 값부터 출력해야겠다
최장 거리 배열을 업데이트하는 구현에 실패했습니다..🥲
위상 정렬을 공부하고 나니 기존에 떠올렸던 풀이가 위상 정렬과 비슷한 것 같아서(가령 진입차수 배열 등..) 신기하고 뿌듯했습니다.
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = 1 << 30;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
cin >> n >> m;
vector<vector<int>> g(n + 1);
vector<int>inDgree(n + 1, 0);
int a, b;
for (int i = 0;i < m;i++) {
cin >> a >> b;
g[a].push_back(b);
inDgree[b] += 1;
}
priority_queue<pair<int, int>> pq;
queue<int>q;
for (int i = 1;i <= n;i++) {
if (inDgree[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int t = q.front();
q.pop();
cout << t << ' ';
for (int x : g[t]) {
inDgree[x]--;
if (inDgree[x] == 0) {
q.push(x);
}
}
}
}
비검사 예외 : 예외 처리 강제하지 않음 → 사용자가 할 수 있는 일이 없거나 종료시키는 것이 바람직한 경우
비검사 예외로 만들기 위해서는 RuntimeException을 상속해야 한다.
Exception을 상속할 경우 try/catch 또는 throws를 통해 예외 처리를 한다.
[DivideException에서 RuntimeException을 상속]
package org.opentutorials.javatutorials.exception;
class DivideException extends RuntimeException {
DivideException() {
super();
}
DivideException(String message) {
super(message); // 부모 클래스의 생성자를 호출할 때 메시지 전달
}
}
class Calculator {
int left, right;
public void setOperands(int left, int right) {
this.left = left;
this.right = right;
}
public void divide() {
if (this.right == 0) {
throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
}
System.out.print(this.left/this.right);
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOperands(10, 0);
c1.divide();
}
}
[DivideException에서 Exception을 상속 : try/catch로 검사 예외를 처리]
package org.opentutorials.javatutorials.exception;
class DivideException extends Exception {
DivideException() {
super();
}
DivideException(String message) {
super(message); // 부모 클래스의 생성자를 호출할 때 메시지 전달
}
}
class Calculator {
int left, right;
public void setOperands(int left, int right) {
this.left = left;
this.right = right;
}
public void divide() {
try {
if (this.right == 0) {
throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
}
System.out.print(this.left/this.right);
}
catch(DivideException e) {
e.printStackTrace();
}
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOperands(10, 0);
c1.divide();
}
}
[DivideException에서 Exception을 상속 : try/catch로 검사 예외를 처리]
package org.opentutorials.javatutorials.exception;
class DivideException extends Exception {
DivideException() {
super();
}
DivideException(String message) {
super(message); // 부모 클래스의 생성자를 호출할 때 메시지 전달
}
}
class Calculator {
int left, right;
public void setOperands(int left, int right) {
this.left = left;
this.right = right;
}
public void divide() throws DivideException{
if (this.right == 0) {
throw new DivideException("0으로 나누는 것은 허용되지 않습니다.");
}
System.out.print(this.left/this.right);
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOperands(10, 0);
try {
c1.divide();
}
catch (DivideException e) {
e.printStackTrace();
}
}
}
equals() 메소드를 직접 구현해야 한다면 hashCode() 메소드도 함께 구현해야 한다.
자식이 부모가 될 때는 자동으로 형변환 된다.
Object obj = s2
부모가 자식이 될 때는 명시적으로 형변환해야 한다.
Student s = (Student)obj;
4.3 finalize
객체가 소멸될 때 호출되기로 약속한 메소드
사용할 일이 거의 없는 메소드이다. 사용을 권장하지 않는다.
4.4 clone
객체를 복제한다.
복제 가능한 객체라는 사실을 자바 가상 머신에 알려줘야 한다. 따라서 Cloneable이라는 인터페이스를 구현한다.
그러나 Cloneable은 비어있는 인터페이스로 클래스가 복제 가능함을 자바 가상머신에게 알려주기 위한 구분자에 불과하다.
clone() 메소드의 접근 제어자는 protected이기 때문에 반드시 메소드를 public 접근 제어자로 오버라이딩해야 한다.
clone() 메소드는 Exception을 상속해서 예외 처리가 필수적이다.
5. enum
enum은 열거형이라고도 한다.
열거형은 서로 연관된 상수의 집합이다.
package org.opentutorials.javatutorials.constant;
enum Fruit {
APPLE, PEACH, BANANA;
}
enum Company {
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
Fruit type = Fruit.APPLE;
switch (type) {
case APPLE:
System.out.println(57 + " kcal");
break;
case PEACH:
System.out.println(34 + " kcal");
break;
case BANANA:
System.out.println(93 + " kcal");
break;
}
}
}
enum은 사실상 클래스이므로 생성자를 가질 수 있다.
열거형에 포함된 상수를 values() 메소드를 통해 상수가 담긴 배열을 가져올 수 있다.
6. 참조
데이터 타입을 생성할 때 new를 통해 생성하는 것들은 기본 데이터 타입이 아니고 참조형 또는 참조 데이터 타입이다.
package org.opentutorials.javatutorials.reference;
class A {
public int id;
A(int id) {
this.id = id;
}
}
public class ReferenceParameterDemo {
static void _value(int b) {
b = 2;
}
public static void runValue() {
int a = 1;
_value(a);
System.out.println("runvalue, " + a);
}
static void _reference1(A b) {
b = new A(2);
}
public static void runReference1() {
A a = new A(1);
_reference1(a);
System.out.println("runReference1, " + a.id);
}
static void _reference2(A b) {
b.id = 2;
}
public static void runReference2() {
A a = new A(1);
_reference2(a);
System.out.println("runReference2, " + a.id);
}
public static void main(String[] args) {
runValue(); // runValue, 1
runReference1(); // runReference1, 1
runReference2(); // runReference2, 2
}
}
package org.opentutorials.javatutorials.generic;
import java.net.Inet4Address;
class EmployeeInfo {
public int rank;
EmployeeInfo(int rank) {
this.rank = rank;
}
}
class Person<T, S> {
public T info;
public S id;
Person(T info, S id) {
this.info = info;
this.id = id;
}
}
public class GenericDemo {
public static void main(String[] args) {
EmployeeInfo e = new EmployeeInfo(1);
Integer i = 10;
Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
// 제네릭을 명시적으로 언급하지 않고 생략할 수 있다.
// Person<EmployeeInfo, Integer> p1 = new (e, i);
}
}
7.1 제네릭의 제한
extends 키워드를 이용해 특정 데이터 타입만 오도록 할 수 있다.
package org.opentutorials.javatutorials.generic;
abstract class Info {
public abstract int getLevel();
}
class EmployeeInfo extends Info {
public int rank;
EmployeeInfo(int rank) {
this.rank = rank;
}
public int getLevel() {
return this.rank;
}
}
class Person<T extends Info> { // Info 클래스의 자식만 T로 올 수 있다
public T info;
Person(T info) {
this.info = info;
}
}
public class GenericDemo {
public static void main(String[] args) {
Person p1 = new Person(new EmployeeInfo(1));
// String은 Info의 자식이 아니기 때문에 에러 발생
// Person<String> p2 = new Person<String>("부장");
}
}