-
프코전-자바편 1~2장자료구조와 알고리즘/알고리즘 2023. 3. 30. 21:31
1장
-코드를 짤 때 흔히하는 실수
코드를 짤 때 가독성과 역할을 충분히 고려하지 못하고 쌓아올리기 시작하면,
어느순간 코드를 수정하는 것 보다 갈아 엎는 것이 나을 때가 생긴다.
이러한 상황을 방지하기 위해서 코드를 작성할 때 가독성과 역할을 신경 쓰며 문제를 단계별로 나누어 해결해보자
-디버깅과 시행착오 줄이기
> 코드를 단계별로 작성하라
> 하나의 단계를 작성하고 검증하라
> 단계 검증이 실패하면, 실패한 단계에서 더 자세히 로그를 찍어보자
- 실습 -전화번호부 만들기
사용자가 입력한 전화번호를 가진 사람들을 전화번호부에서 검색하는 기능을 구현해보자
처음에는 입력과 검색 모든 과정을 한 번에 생각하면서 코드를 작성하려 할 것이다. 이는 가독성이 떨어지는 코드 작성의 시발점이다. 전화번호를 검색하는 간단한 기능에서도 여러가지 단계를 걸쳐 설계할 수 있다.
>전화번호는 어떤 형식으로 나타낼 것인가?
> 전화번호부에 저장되어 있는 사람들은 어떻게 나타낼 것인가
> 사람과 전화번호는 어떻게 비교할 것인가?
> 전화번호부는 어떤 형식으로 나타낼 것인가?
1. 전화번호 나타내기
전화번호는 여러 형식으로 표기할 수 있다. 010-xxxx 010/xxxx, 010xxx이런 식으로 표기할 수 있다.
따라서 사용자가 어떤식으로 입력할 지 알 수 없다. 따라서 사용자의 입력을 변환하는 코드를 작성해보자
private static class PhoneNumber { //main메서드에 쓰려고 static public final String phonenumber; public PhoneNumber(String rawPhoneNumber){ this.phonenumber = rawPhoneNumber.replaceAll("[^0-9]",""); } @Override public String toString(){ return "Phonenumber{"+"phoneNumber ='"+phonenumber+'\''+'}'; } } public static void main(String[] args){ System.out.println(new PhoneNumber("010-1111-1111")); System.out.println(new PhoneNumber("010/1111/1111")); System.out.println(new PhoneNumber("010 1111 1111")); }
별도의 static 클래스로 PhoneNumber를 만들고 phonenumber 멤버에 입력받은 문자열을 적절한 변환한 결과를 담을 수 있도록 정규식을 이용해서 만들었다.
2. 전화번호부의 사람 나타내기
private static class Person{ public final String name; private final List<PhoneNumber> numbers; public Person(String name){ this.name=name; numbers = new ArrayList<>(); } public void addPhoneNumber(PhoneNumber number){ numbers.add(number); } @Override public String toString(){ return "Person{"+"name='"+name+'\''+", numbers="+numbers+'}'; //리스트 toString [멤버.toString,멤버.toString]이런식 }
전화번호에 저장되는 사람 객체를 만들었다. 한 사람은 여러가지 전화번호를 가질 수 있다.(전화번호list로 가짐)
addPhoneNumber()메서드로 하나의 사람 객체에 여러 전화번호를 추가하도록 만들었다.
매개변수로 PhoneNumber객체만을 두어 전화번호 형식을 검사하는 역할은 하지않도록 했다.
만약 String으로 받아서 형식까지 위 메서드에서 직접 검사해야했으면, 후에 전화 번호에 국가코드를 추가해야한다거나, 전화번호 형식이 바뀌거나하면, 일일이 코드를 수정해야할 것이므로, 좋지 않은 코드가 될 수 있다.
*name과 numbers는 생성자에서 정해진 값 이후에는 변경x final로 의도치 않은 변경 막았다. list는 임의로 값을 변경할 수 있는 변수이므로 private, String은 값이 불변이고 읽을 수 만 있으므로 public으로 했다.
->numbers를 public으로 하면, numbers에 새로운 list자료형을 할당하는 것은 불가능하지만, numbers 내부에 저장된 데이터를 변경하는 것은 가능하다. 이를 방지하기 위해 private인 것
3. 사람과 전화번호 비교하기
public boolean hasPhoneNumber(PhoneNumber number){ return numbers.contains(number); }
Person클래스에 객체가 해당 전화번호를 가지고 있는지 확인하는 메서드를 작성하였다.
ArrayList에 contains()은 내부적으로 내부 데이터에 equals()를 사용하므로, 정확한 결과를 위해서 PhoneNumber클래스에
Equals()를 오버라이딩 해두어야한다.
@Override public boolean equals(Object o){ if(!(o instanceof PhoneNumber))return false; return this.phonenumber.equals(((PhoneNumber) o).phonenumber); }
4 전화번호부 나타내기
private static class PhoneBook{ private final List<Person> people; private PhoneBook(){ people = new ArrayList<>(); } public void addPerson(Person person){ people.add(person); } public String toString(){ return "PhoneBook{"+"people'"+people+'}'; } }
전화번호부를 만들어서 Person객체를 리스트로 관리하도록 했다.
하지만, 이 코드는 한가지 문제점이 있는데, 하나의 객체를 여러번 등록할 수 있다는 점이다.
이를 막기위해 ArrayList()를 set으로 바꿔두자
public Person search(PhoneNumber number){ return people.stream().filter(p -> p.hasPhoneNumber(number)).findFirst().orElse(null); }
전화번호로 사람을 찾는 메서드 스트림을 이용하였다.
public Person search2(PhoneNumber number){ for(Person i : people){ if(i.hasPhoneNumber(number)) return i; } return null; }
for문으로 처리할 수 있다.
위와 같은 방법으로 오류를 줄이면서 단계별로 완성하는 습관을 들이는 것은 아주 중요하다!
*contains가 equals()를 사용한다는 점, List나 set은 toString()이 [멤버]로 정의되어있고,
멤버에 toString()을 오버라이딩해야 list를 출력해야 원하는대로 나온다.
*하나씩 객체를 확장해 나가는 것과 객체별 포함관계 혹은 리스트를 이용한 포함관계 확장하는 것 연습..
*static inner 클래스 적극활용을 고려해보자
2. 시간복잡도
시간복잡도란 코드 혹은 알고리즘의 실행 시간과 데이터의 상관관계이다.
-빅오표기법: 알고리즘이 겪을 수 있는 최악의 경우에 걸리는 시간과 입력간의 상관관계 표기
-입력 데이터 개수별 사용 가능한 시간 복잡도 알고리즘
> 1억번의 연산을 수행하면 1초가 걸린다고 어림짐작하자.
(절대적인 기준은 아니고 어림짐작 일종의 커트라인으로 넘기지 않는 편이 좋다)
> 코드를 작성하기 전에 풀이를 먼저 생각하고 시간 복잡도를 이용하여 효율성 검증하고 코드를 작성하는게 좋다.
2.1 시간 복잡도 계산하기
>반복횟수 세어보기
>어림짐작해보기 :
- 시간 복잡도에서는 곱하거나 더해지는 상수는 나타내지 않는다.
- 또한 가장 영향을 미치는 항만 표기한다 ex 1/2N^2 + 3/2N + 1 = O(N^2) -- 상수버리고, 최고차항만 따지기
참고자료:
프로그래머스 코딩테스트 문제풀이 전략 자바편 -김현이 저
'자료구조와 알고리즘 > 알고리즘' 카테고리의 다른 글
자알인 - 스택 & 큐 (0) 2024.01.30 자알인 (1) 코딩테스트 팁 (0) 2024.01.03 다이나믹 프로그래밍 (0) 2023.04.13 여러가지 수학 (0) 2023.04.11 스택과 문제들 풀면서 얻은.. (0) 2023.04.05