//////
Search

알고리즘(최대값 구하기), DB by 곽철민

태그
2022/10/12 16:47
사람
최종 편집 일시
2022/10/12 17:21

알고리즘 기초

CodeUp 2081: 최대값 I

9개의 서로 다른 자연수가 주어질 때, 이들 중 최대값을 찾고 그 최대값이 몇 번째 수인지를 구하는 프로그램을 작성하시오. 예를 들어, 서로 다른 9개의 자연수 3, 29, 38, 12, 57, 74, 40, 85, 61 이 주어지면 이들 중 최대값은 85이고, 이 값은 8번째 수이다.
Plain Text
복사
문제가 존재하는 code
정답 code

CodeUp 4596: 최대값 2

<그림 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 을 작성하는 코드 만들기
파일 만들기
.csv에서 line별로 읽어오기
JavaObject Hospital()
id(PK)
address
district
category
emergency_room
name
subdivision
line별로 읽어와서 필요한 정보만 뽑아서 Object에 담기
setSubdivision()
생성자에서 setDistrict() 추가 생성해서 호출
address.split(””) —> [0]+ “” + [1] —> 서울특별시 금천구 형태로 만들수 있음
subdivision은 병원이름(name)을 기준
피부과, 성형외과, 외과, 내과, 소아과, 가정의학과, 치과 등의 단어가 포함 되어 있으면
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, 개방 폐쇄의 원칙)

DB개념 관련 참고 사이트