코틀린-안드로이드

12일차)알고리즘 문제(개인정보 수집 유효기간), 코틀린 문법 강의 1주차(특징, 장점, 단축키), 코틀린 문법 강의 2주차(코딩 컨벤션, 입출력, 자료형, 변수와 상수, 연산자, 조건식, 반복문), 코틀린 문법 강의 3주차(메소드, 클래스 설계, 생성자, 객체, 상속, 오버라이딩, 오버로딩, 인터페이스)

songyooho 2024. 6. 3. 20:47

>알고리즘 문제

 

1. 문제

고객의 약관 동의를 얻어서 수집된 1~n번으로 분류되는 개인정보 n개가 있습니다. 약관 종류는 여러 가지 있으며 각 약관마다 개인정보 보관 유효기간이 정해져 있습니다. 당신은 각 개인정보가 어떤 약관으로 수집됐는지 알고 있습니다. 수집된 개인정보는 유효기간 전까지만 보관 가능하며, 유효기간이 지났다면 반드시 파기해야 합니다.

예를 들어, A라는 약관의 유효기간이 12 달이고, 2021년 1월 5일에 수집된 개인정보가 A약관으로 수집되었다면 해당 개인정보는 2022년 1월 4일까지 보관 가능하며 2022년 1월 5일부터 파기해야 할 개인정보입니다.
당신은 오늘 날짜로 파기해야 할 개인정보 번호들을 구하려 합니다.

모든 달은 28일까지 있다고 가정합니다.

다음은 오늘 날짜가 2022.05.19일 때의 예시입니다.

약관 종류유효기간

A 6 달
B 12 달
C 3 달

번호개인정보 수집 일자약관 종류

1 2021.05.02 A
2 2021.07.01 B
3 2022.02.19 C
4 2022.02.20 C
  • 첫 번째 개인정보는 A약관에 의해 2021년 11월 1일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.
  • 두 번째 개인정보는 B약관에 의해 2022년 6월 28일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능합니다.
  • 세 번째 개인정보는 C약관에 의해 2022년 5월 18일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.
  • 네 번째 개인정보는 C약관에 의해 2022년 5월 19일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능합니다.

따라서 파기해야 할 개인정보 번호는 [1, 3]입니다.

오늘 날짜를 의미하는 문자열 today, 약관의 유효기간을 담은 1차원 문자열 배열 terms와 수집된 개인정보의 정보를 담은 1차원 문자열 배열 privacies가 매개변수로 주어집니다. 이때 파기해야 할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요.


제한사항

  • today는 "YYYY.MM.DD" 형태로 오늘 날짜를 나타냅니다.
  • 1 ≤ terms의 길이 ≤ 20
    • terms의 원소는 "약관 종류 유효기간" 형태의 약관 종류와 유효기간을 공백 하나로 구분한 문자열입니다.
    • 약관 종류는 A~Z중 알파벳 대문자 하나이며, terms 배열에서 약관 종류는 중복되지 않습니다.
    • 유효기간은 개인정보를 보관할 수 있는 달 수를 나타내는 정수이며, 1 이상 100 이하입니다.
  • 1 ≤ privacies의 길이 ≤ 100
    • privacies[i]는 i+1번 개인정보의 수집 일자와 약관 종류를 나타냅니다.
    • privacies의 원소는 "날짜 약관 종류" 형태의 날짜와 약관 종류를 공백 하나로 구분한 문자열입니다.
    • 날짜는 "YYYY.MM.DD" 형태의 개인정보가 수집된 날짜를 나타내며, today 이전의 날짜만 주어집니다.
    • privacies의 약관 종류는 항상 terms에 나타난 약관 종류만 주어집니다.
  • today와 privacies에 등장하는 날짜의 YYYY는 연도, MM은 월, DD는 일을 나타내며 점(.) 하나로 구분되어 있습니다.
    • 2000 ≤ YYYY ≤ 2022
    • 1 ≤ MM ≤ 12
    • MM이 한 자릿수인 경우 앞에 0이 붙습니다.
    • 1 ≤ DD ≤ 28
    • DD가 한 자릿수인 경우 앞에 0이 붙습니다.
  • 파기해야 할 개인정보가 하나 이상 존재하는 입력만 주어집니다.

2. 솔루션

class Solution {
    fun solution(today: String, terms: Array<String>, privacies: Array<String>): IntArray {
        var answer: IntArray = intArrayOf()
        for(i:Int in 0..privacies.size-1){
            var exp=0
            val spl=privacies[i].split(" ")
            for(j:Int in 0..terms.size-1){
                if(terms[j][0]+""==spl[1]){
                    exp=terms[j].split(" ")[1].toInt()
                }
            }
            
            val date=date(spl[0],exp)
            if(date<=today){
                answer+=i+1
            }
        }
        return answer
    }
    
    fun date(s:String, exp:Int):String{
        val tmp=s.split(".")
        var dates=mutableListOf(tmp[0].toInt(),tmp[1].toInt(),tmp[2].toInt())
        dates[1]+=exp
        if(dates[1]%12==2&&dates[2]>28){
            dates[1]++
            dates[2]-=28
        }
        if(dates[1]>12){
            dates[0]+=dates[1]/12
            dates[1]%=12
        }
        
        //12월달인 경우 위의 연산에서 연수는 1이 더 올라가고 0월로 나옴
        //=>12월로 고치고 추가로 올라간 1년을 다시 내림
        if(dates[1]==0){
            dates[1]=12
            dates[0]--
        }
        val year=dates[0].toString()
        val month=if(dates[1]<10) "0${dates[1]}" else dates[1].toString()
        val day=if(dates[2]<10) "0${dates[2]}" else dates[2].toString()
        return year+"."+month+"."+day
    }
}

1)fun date

-가입일과 유효기간을 받아 만료시키를 계산하는 함수

-문자열로 된 가입일을 년도, 월, 일로 나누어 저장

-유효기간을 더해서 만료일을 계산하고 그 중간에 예외 케이스를 따로 계산

=>날짜가 28보다 큰데 만료달이 2월로 나오는 경우: 달을 1올리고 일자에 28을 빼서 계산

=>달의 값이 12를 넘어가는 경우: 12로 나눈 몫을 년도에 더해주고 나머지는 월에 나둠. 이때 12월이 되는 경우는 0월로 처리되므로 년도를 도로 1빼주고 월을 12월로 바꿔줌.

2)솔루션 본문

-terms를 이용해 유효기간을 찾음

-date 함수로 만료일을 구함

-String의 사전식 비교: 부등호를 이용하여 사전식 비교를 함(사전식으로 뒤에 오는 값이 더 큼)

=>today보다 만료일이 사전식으로 더 작은 값은 유효기간이 지난것이므로 파기

 

 

 

 

>코틀린 문법 강의 1주차

1. 코틀린의 특징

-JVM언어(java같은것들)과 완벽히 호환

-직관적이고 간결

-Null처리에 높은 안정성

 

2. 코틀린의 장점

-생산성이 높음

-높은 품질의 프로그램 제작가능

-간결하고 안전하게 비동기 처리 수행가능

 

3. 유용한 단축키

-라인 지우기:  Ctrl + Y

-주석처리: Ctrl + /

-자동 포커싱: Esc =>커서 깜빡임이 사라졌을때 키는 용도

-프로젝트 전체에서 찾기: Ctrl + Shift + F

-키보드로 라인 드래그: Shift + 방향

-문장 맨앞/맨뒤 이동: Home / End

 

 

 

>코틀린 문법 강의 2주차

 

1. 코딩 컨벤션(Coding Convention)

1)의미: 다른 사람도 이해하기 쉽게 코드 작성하는 규칙. 언어마다 상이함.

 

2)표기법 종류

<1>카멜케이스

-첫단어제외하고 단어앞글자를 대문자로 작성

-변수, 메소드 이름에 사용

<2>스네이크케이스

-단어 사이에 _(언더바)를 넣어 사용

-상수 이름에 사용

<3>파스칼케이스

-모든 단어 첫 글자를 대문자로 작성

-클래스명에 사용

 

 

2. 입출력

1) 의미

-출력(Output): 프로그램에서 장치로 데이터 전송

-입력(Input): 장치에서 데이터를 프로그램으로 불러옴

 

2)사용

-출력: print()-줄 바꿈 없음-, println() -출력 후 줄 바꿈. 변수는 "${변수}" 같이 사용

-입력: readLine() - 장치로 입력한 값이 문자열로 변환되어 저장 -

 

 

3.자료형(단위는 비트)

1)정수:Long(64), Int(32), Short(16), Byte(8)

2)실수:Double(64), Float(32)

3)Boolean(8)

4)문자열:String

 

 

4. 변수와 상수

1)변수:var, 값을 변경할 수 있음

2)상수:val, 값 변경 불가

 

 

5. 연산자

1)산술 연산자: +, -, *, /, %

2)대입 연산자: =

3)복합대입 연산자: (산술연산자) + =

4)증감 연산자

-종류: ++, --

-전위, 후위연산자: 앞에 오는 경우 연산자가 포함된 라인의 코드 실행 전에 연산이 적용됨. 반대의 경우 코드 실행 후에 연산이 적용됨.

5)비교(논리)연산자:<,>,<=,>=,==,!=

 

6. 조건문

1)종류: if..else, when

@when 사용법:

-형태

when(변수나 상수){
	
    case1 -> 결과1
    .
    .
    .
    else -> 결과
}

-마지막에 else가 반드시 들어가야함

-case 부분에는 값, 범위(in a..b), 타입비교(is 자료형) 등이 들어감

-조건식 사용: 다음과 같이도 사용 가능

when{
	
    조건식1 -> 결과1
    조건식2 -> 결과2
    .
    .
    .
    else -> 결과
}

 

 

6. 반복문

1) 종류: for, while

2) break, continue

-break: 가장 가까운 반복문에서 탈출

-continue: 반복문의 현 시점 아래 코드를 실행하지 않고 다음 루프로 넘어감

 

 

>코틀린 문법 강의 3주차

 

1. 메소드(함수)

-구조

fun 메소드이름(변수명:자료형,...):반환자료형{
	코드 로직
}

 

2. 클래스

1)객체지향 프로그래밍( Object Oriented Programming (OOP))

-코틀린은 모든것이 클래스형태라 객체화 가능

-필요 데이터를 추상화해 상태와 행위를 가진 객체 생성

-객체간 적절한 결합으로 유지보수를 용이하게 함

-5대 키워드: 클래스, 추상화, 캡슐화, 상속, 다형성

@다형성: 같은 이름의 메소드나 연산자가 다른 클래스에대해 다른 동작을 하는것

=>오버라이딩과 오버로딩과 연관

@추상화: 객체의 공통적인 속성과 기능을 추출해 정의하는

 

2)클래스 구조

class 클래스명{
    프로퍼티1
    .
    .
    
    메소드1
    .
    .
}

 

 

3)클래스 종류

<1>데이터 클래스

-프로퍼티만 가진 클래스

-1개 이상 프로퍼티를 가져야함

-유용한 메소드를 자동 생성

  • hashCode(): 객체를 구분하기 위한 고유값을 리턴
  • eauals(): 동일한 객체인지 비교해서 true 또는 false를 리턴
  • copy(): 현재 객체의 모든 정보를 복사해서 새로운 객체를 리턴
  • toString(): 현재 객체의 모든 정보(프로퍼티)를 출력
  • getXXX()/setXXX(매개변수): 변수의 값을 리턴하거나 설정(XXX는 프로퍼티의 변수명)

-구조

data class 클래스이름 {
    프로퍼티1
    프로퍼티2
}

 

<2>오브젝트 클래스

-실행과 동시에 인스턴스화함

-java의 static과 같은 키워드

 

<3>실드(sealed) 클래스

-상속 받을 수 있는 자식클래스를 미리 정의

-무분별한 상속 방지

-구조

sealed class 부모클래스 {
	class 자식클래스1 : 부모클래스생성자
	class 자식클래스2 : 부모클래스생성자
}

 

<4>열거(enum) 클래스

-여러곳에 동일 상수정의 혹은 상수 외부에 관련 변수나 함수 정의시 관리 어려움

-enum class를 이용해 상수값 관리 지점을 줄여줌

-구조 예시

enum class 클래스1 {
    C, JAVA, KOTLIN
}
//위의 constant들은 각각이 오브젝트

enum class 클래스2(val code: Int) {
    C(10),
    JAVA(20),
    KOTLIN(30)
}
//val생략가능

//숫자가 여러개인경우는 아래처럼
enum class 클래스3(val a: Int, val b) {
    C(10,20),
    JAVA(20,30),
    KOTLIN(30,40)
}


fun main() {
    println(클래스1.C.toString()) // 출력: C
    println(클래스2.KOTLIN.code) // 출력: 30
    println(클래스2.KOTLIN.name) // 출력: KOTLIN
}

//위의 두가지 방식으로 구현가능

 

 

3. 생성자

@주생성자와 부생성자는 명시적 생성자라 지칭함

1)기본생성자: class옆에 매개변수가 없는 경우 기본적으로 생성됨

2)주생성자

-클래스명 옆에 매개변수를 포함한 소괄호를 주생성자라함

@init:인스턴스 생성시 실행되는 본문. //부 생성자와 함께있는 경우 init의 본문이 가장먼저 실행됨

=>구조

init {
	println("매개변수없는 생성자 실행 완료!")
}

//프로퍼티 아래에 적힘

3)부생성자

-구조

constructor(매개변수,...) {
	본문
}

-주생성자가 있는 경우에는 주생성자를 참조해야한다

=>소괄호 옆에 :this(주생성자의 매개변수들) //이러면 주생성자가 실행되고 이후 부생성자 실행됨

=>부생성자들 끼리도 참조가능. 참조된 생성자가 먼저 실행됨.

 

4. 객체

1)객체란: 클래스 타입으로 선언된것들. 모든 인스턴스를 포함하는 개념

2)인스턴스란: 클래스 형태의 객체 실체화시 인스턴스가 생성됨. 메모리 공간 차지

3)클래스 실체화 과정: 객체의 위치정보를 변수에 저장하고 필요시 참조해서 실제 메모리내 값에 접근

 

 

5. 상속

1)상속 조건: 부모클래스에서 class키워드 앞과 각 멤버의 앞에 open키워드를 붙여야 함

2)다형성 구현

3)클래스 수정시 부모클래스만 수정하면되서 편리함

 

6. 오버라이딩

1)상속받은 부모 클래스의 프로퍼티나 메소드를 재설계가능

2)단축키: Ctrl + O

 

7. 오버로딩

1)매개변수 개수나 자료형을 다르게해 동일 이름의 메소드를 여러개 생성가능

2)반환형을 오버로딩에 영향 X

3)예시: 정수형끼리 더하기하는 함수와 실수형끼리 더하기 하는 함수 생성시 오버로딩으로 동일 이름의 함수 두개를 만들 수 있다. 

 

8. 인터페이스

1)사용: 부모클래스로부터 상속 받는것 이외에 더 많은 메소드 사용을 원할 경우 사용

2)구조

interface 인터페이스이름 {
    fun 메소드이름()
    .
    .
}

3)적용 예시

interface Shape {
    fun calculateArea(): Double
}

class Circle(val radius: Double) : Shape {
    override fun calculateArea(): Double {
        return Math.PI * radius * radius
    }
}