알고리즘 기초
9개의 서로 다른 자연수가 주어질 때, 이들 중 최대값을 찾고 그 최대값이 몇 번째 수인지를 구하는 프로그램을 작성하시오.
예를 들어, 서로 다른 9개의 자연수
3, 29, 38, 12, 57, 74, 40, 85, 61
이 주어지면 이들 중 최대값은 85이고, 이 값은 8번째 수이다.
Plain Text
복사
문제가 존재하는 code
정답 code
<그림 1>과 같이 9×9 격자판에 쓰여진 81개의 자연수가 주어질 때, 이들 중 최대값을 찾고 그 최대값이 몇 행 몇 열에 위치한 수인지 구하는 프로그램을 작성하시오.
예를 들어, 다음과 같이 81개의 수가 주어지면 이들 중 최대값은 90이고, 이 값은 5행 7열에 위치한다.
Plain Text
복사
code
2차원 배열의 진행순서
[맥북 단축키]
Cmd + Opt + L: 코드 정렬
Cmd + Shift + 8: 모드 바꾸기 (block <-> column)
Ctrl + G: 같은 단어 찾기 (이후 shift + 방향키로 선택)
(많이 선택되면 Crtl + Shift + G로 하나씩 취소할 수 있음)
Plain Text
복사
다형성 적용해서 최소값 구하기
Q. 최대값과 최소값을 동시에 구하려면?
code
•
interface 와 callback 을 이용해서 boolean 을 리턴하는 조건만 바꾼다.
[callback 작동 방식]
callback → 호출한 메서드로 다시 간다.
실행 순서
ex) max → getMaxOrMin → max
Plain Text
복사
[적용한 디자인 패턴: 템플릿 - 콜백 패턴]
•
템플릿 - 콜백 패턴: 변화되는 부분을 매번 클래스로 만들지 않고, '익명 내부 클래스'로 바로 생성하여 이용
◦
템플릿: '템플릿'이라는 키워드는 개발 영역에서도 자주 사용하는데 정해져 있는 '틀'이라고 할 수 있다.
◦
콜백: 콜백은 실행되기 위한 특정 로직을 말하며 자바에서는 콜백을 매개변수로 주고 받기 위해 '오브젝트'에 담아서 전달한다. (위의 코드에서는 Compare 를 구현한 오브젝트의 max(); 메서드에 원하는 로직을 담아 전달한다.)
•
즉, 템플릿-콜백 패턴이란 정해진 틀안에서, 변화되는 부분만 유동적으로 받아 수행하는 패턴이다. 위의 코드로 말하면 템플릿은 getMaxOrMin(), 콜백은 max(), min() 같은 실행되기 위한 로직을 말한다.
context 라는 이름을 짓는 경우
- 일부만 바뀌는 경우,
바뀌는 부분을 제외한 바뀌지 않는 부분을
Template Method 로 분리 했을 때
ex) readLineContext() parser()만 바뀜
- MaxAndMin 의 경우 return a > b, return a < b 인 경우
Plain Text
복사
Intellij 단축키
인텔리제이 단축키
Sql Insert 하는 스크립트를 만드는 로직
데이터 분석 방법
•
공공데이터 (8.6 mb, 19040건)
•
요구사항
1.
병원 분류명이 총 몇 가지 일까?
2.
병원 분류별로 몇 개의 병원이 있을까? ex) 의원: x개, 한방병원:y개, 치과의원: z개…
3.
병원 분류가 몇 가지 일까?
4.
서울의 구별로 각 병원이 몇개 있을까? ex) 서울특별시 금천구의 의원, 한방병원, 치과병원, … 이 각 몇 개 인지
5.
병원이 가장 많은 구는 어디일까?
6.
이비인후과, 외과, 내과, 소아과, 피부과, 성형외과는 각 몇개일까?
⇒ DB를 이용해 분석 → 병원 정보 제공 앱을 만들기 위한 백엔드 서버에 활용할 수 있다.
데이터 모델링
데이터 모델링이란?
정보시스템 구축의 대상이 되는 업무 내용을 분석하여 이해하고 약속된 표기법에 의해 표현하는걸 의미한다
[요구사항 분석 순서]
•
요구사항 분석: 어떠한 업무를 시작하기 전에 해당하는 업무에 대해서 파악하는 단계, 고객이 무엇을 원하는지 고객의 관점에서 파악한다.
1.
개념적 설계 : 데이터 간의 관계를 구상하는 단계
2.
논리적 설계 : 구체화된 업무 중심의 데이터 모델을 만들어나가는 단계
3.
물리적 설계: 데이터를 관리할 데이터베이스를 선택하고, 선택한 데이터베이스에 실제 테이블을 만드는 작업을 하는 단계
실습: 서울특별시_병의원
1.
개념적 설계
2.
논리적 설계: 테이블 정의서 작성
seoul_hospital
Column Name | Description | Type | ex |
id(PK) | VARCHAR(8) | A1120837 | |
address | 전체 주소 | VARCHAR(90) | |
discritct | 서울특별시 OO구 | VARCHAR(15) | 서울특별시 금천구 |
category | 병원 분류 | VARCHAR(1) | A: 종합병원
B: 병원
C: 의원
D: 요양병원
E: 한방병원
G: 한의원
I: 기타
M: 치과병원
N: 치과의원
R: 보건소 |
emergency_room | 응급실 운영여부 | 1: 운영
2: 운영X | |
name | 해당 병원의 이름 | VARCHAR(40) | 가산기대찬의원 |
subdivision | 세부 분과 | VARCHAR(10) | 피부과, 성형외과, 외과, 내과, 소아과, 가정의학과,
치과 등 |
3.
물리적 설계: Create Table
a.
Entity(Table) seoul_hospital 에 Row(Record) Insert 하기
sql 문으로 insert
INSERT INTO `likelion-db`.`seoul_hospital`
(`id`,`address`,`district`,`category`,`emergency_room`,`name`,`subdivision`)
VALUES
('A1120837',
'서울특별시 금천구 벚꽃로 286 삼성리더스타워 111~114호 (가산동)',
'서울특별시 금천구','C',2,'가산기대찬의원',null);
SELECT * FROM `likelion-db`.seoul_hospital;
SQL
복사
파일로 db에 insert
1.
파일에 sql문 작성 후 저장
2.
workbench에서 .sql 스크립트 불러오기
3.
불러온 .sql 스크립트 실행
Insert Into 작성 팁
Java로 .sql 파일 만들기 개요
서울특별시_병의원 정보가 들어있는 .csv파일을 읽어서
seoul_hospital_insert.sql 을 작성하는 코드 만들기
id(PK) |
address |
district |
category |
emergency_room |
name |
subdivision |
•
setSubdivision()
•
address.split(””) —> [0]+ “” + [1] —> 서울특별시 금천구 형태로 만들수 있음
•
피부과, 성형외과, 외과, 내과, 소아과, 가정의학과, 치과 등의 단어가 포함 되어 있으면
ex) 피부과가 포함 되어 있으면 피부과
CSV파일을 DB에 넣을 수 있게 가공하기
1.
파일 읽어와서 String List로 만들기
package com.line;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class LineReader {
List<String> readLines(String filename) throws IOException {
List<String> result = new ArrayList<>();
BufferedReader br = new BufferedReader(new FileReader(filename));
String str;
while ((str = br.readLine()) != null) {
result.add(str);
}
return result;
}
public static void main(String[] args) throws IOException {
String filename = "/Users/jangseohyeon/Downloads/서울시 병의원 위치 정보.csv";
LineReader lr = new LineReader();
List<String> lines = lr.readLines(filename);
System.out.println(lines.size());
}
}
Java
복사
2.
Parser<T> interface
package com.line.parser;
public interface Parser<T> {
T parse(String str);
}
Java
복사
다양한 타입을 return 할 수 있도록 <T>로 만들어준다. -> 다형성 적용 위함
어떤 파일이 들어오는지에 따라서 Object 가 결정된다.
ex) 병원 데이터 parsing => Hospital, 인구 이동 통계 parsing => PopulationStatistics
Plain Text
복사
3.
Parser 의 구현체 - HospitalParser class
package com.line.parser;
import com.line.domain.Hospital;
public class HospitalParser implements Parser<Hospital> {
@Override
public Hospital parse(String str) {
String[] splitted = str.split(",");
return new Hospital(splitted[0]);
}
}
Java
복사
4.
Object 를 위해 domain 패키지를 만들어 Hospital class 를 만든다.
package com.line.domain;
public class Hospital {
private String id;
public Hospital(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
Java
복사
5.
실행을 위한 Main class 생성
package com.line;
import com.line.domain.Hospital;
import com.line.parser.HospitalParser;
import java.io.IOException;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
LineReader<Hospital> hospitalLineReader = new LineReader<>(new HospitalParser());
String filename = "/Users/jangseohyeon/Downloads/서울시 병의원 위치 정보.csv";
List<Hospital> hospitals = hospitalLineReader.readLines(filename);
System.out.println(hospitals.size());
for (Hospital hospital : hospitals) {
System.out.println(hospital.getId());
}
}
}
Java
복사
6.
수정된 LineReader class
package com.line;
import com.line.parser.Parser;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class LineReader<T> {
Parser<T> parser;
boolean isRemoveColumnName = true;
public LineReader(Parser<T> parser) {
this.parser = parser;
}
List<T> readLines(String filename) throws IOException {
List<T> result = new ArrayList<>();
BufferedReader br = new BufferedReader(new FileReader(filename));
String str;
if (isRemoveColumnName) {
br.readLine();
}
while ((str = br.readLine()) != null) {
result.add(parser.parse(str));
}
return result;
}
}
Java
복사
•
위와 같은 구조는, 인터페이스를 활용하여 다양한 구현체 클래스를 만들어주는 형태입니다.
실행을 위한 Main 클래스
package com.line;
import com.line.domain.Hospital;
import com.line.parser.HospitalParser;
import java.io.IOException;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
LineReader<Hospital> hospitalLineReader = new LineReader<>(new HospitalParser());
String filename = "/Users/jangseohyeon/Downloads/서울시 병의원 위치 정보.csv";
List<Hospital> hospitals = hospitalLineReader.readLines(filename);
System.out.println(hospitals.size());
for (Hospital hospital : hospitals) {
System.out.println(hospital.getId());
}
}
}
Java
복사
•
메인 메소드에서 LineReader 객체 생성 시, HospitalParser() 객체를 생성하도록 합니다.
◦
따라서, lr 이라는 변수명을 가진 객체는 HospitalParser 구현체의 parse() 메소드 기능을 사용할 수 있습니다.
•
이는 파일을 읽는 로직인 readFiles()의 수정 없이,
parse() 메소드의 구현 클래스를 다르게 적용해줌으로써,
파일을 읽을 경우 파싱해주는 작업이 각기 다양하게 작동하는 것과 같이 기능의 확장을 가능하게 해줍니다. → OCP(Open-Closed Principle, 개방 폐쇄의 원칙)
•
위와 같은 구조는, 인터페이스를 활용하여 다양한 구현체 클래스를 만들어주는 형태입니다.
•
이는 파일을 읽는 로직인 readFiles()의 수정 없이,
parse() 메소드의 구현 클래스를 다르게 적용해줌으로써,
파일을 읽을 경우 파싱해주는 작업이 각기 다양하게 작동하는 것과 같이 기능의 확장을 가능하게 해줍니다. → OCP(Open-Closed Principle, 개방 폐쇄의 원칙)