Algorism

알고리즘 - 프로그래머스 문자열 내 마음대로 정렬하기(Swift)

codinglearn 2020. 7. 20. 12:58
반응형

문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 [sun, bed, car]이고 n이 1이면 각 단어의 인덱스 1의 문자 u, e, a로 strings를 정렬합니다.제한 조건

  • strings는 길이 1 이상, 50이하인 배열입니다.
  • strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
  • strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
  • 모든 strings의 원소의 길이는 n보다 큽니다.
  • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.

입출력 예

stringsnreturn

[sun, bed, car] 1 [car, bed, sun]
[abce, abcd, cdx] 2 [abcd, abce, cdx]

입출력 예 설명

입출력 예 1
sun, bed, car의 1번째 인덱스 값은 각각 u, e, a 입니다. 이를 기준으로 strings를 정렬하면 [car, bed, sun] 입니다.

입출력 예 2
abce와 abcd, cdx의 2번째 인덱스 값은 c, c, x입니다. 따라서 정렬 후에는 cdx가 가장 뒤에 위치합니다. abce와 abcd는 사전순으로 정렬하면 abcd가 우선하므로, 답은 [abcd, abce, cdx] 입니다.


문자열 처리 문제조 천천이 생각하면 그렇게 어려운 문제는 아니에요.

1. 입력받은 각문자열의 n번째 자리의 글자를 비교하여 정렬한다.
2. 비교한 n번째 문자열이 동일할 경우 문자열 전체를 비교하여 정렬한다.

 

문자열의 각 n번째 자리를 비교하는 내용은 for문을 사용하셔도 되고, sort함수를 사용하는 방법도 있조.

 

저는 sort함수를 사용하였고요. 그이후에 동일한 값일 경우 각 자리마다 비교를 해야하기 때문에 재귀함수를 사용하였어요.

func solutionA(_ strings:[String], _ n:Int) -> [String] {
    var resultArray = strings
    
    func heap(_ firstArr: [String.Element], _ secondArr: [String.Element], _ tartgetIndex: Int) -> Bool {
        if firstArr[tartgetIndex] < secondArr[tartgetIndex] {
            return true
        } else if firstArr[tartgetIndex] == secondArr[tartgetIndex] {
            return heap(firstArr, secondArr, tartgetIndex + 1)
        } else {
            return false
        }
    }
    
    
    resultArray.sort { first, second in
        let firstArray = Array(first)
        let secondArr = Array(second)
        
        if firstArray[n] < secondArr[n] {
            return true
        } else if firstArray[n] == secondArr[n] {
            return heap(firstArray, secondArr, 0)
        } else {
            return false
        }
    }
    
    return resultArray
}

 

 

먼저 변수를 변경가능하게 복사하여 선언해줍니다.

 

그리고 재귀함수를 선언한 이후에 sort함수를 이용해서 값을 비교해줍니다.

resultArray.sort { first, second in
    let firstArray = Array(first)
    let secondArr = Array(second)
    
    if firstArray[n] < secondArr[n] {
        return true
    } else if firstArray[n] == secondArr[n] {
        return heap(firstArray, secondArr, 0)
    } else {
        return false
    }
}

먼저 각 문자열의 n번째 자리를 확인하기 위해서 Array로 형변환 해줍니다. 

그리고 첫번째 문자와 두번째 문자열의 n번째 위치를 비교하여 값이 작을경우에는 true, 아닐경우에는 false를 반환해주시어 정렬 합니다.

 

그리고 값이 동일할 경우에는 heap함수를 호출하여 true or false를 반환합니다.

 

func heapA(_ firstArr: [String.Element], _ secondArr: [String.Element], _ tartgetIndex: Int) -> Bool {
    if firstArr[tartgetIndex] < secondArr[tartgetIndex] {
        return true
    } else if firstArr[tartgetIndex] == secondArr[tartgetIndex] {
        return heapA(firstArr, secondArr, tartgetIndex + 1)
    } else {
        return false
    }
}

힙 함수도 위의 비교내용과 동일해요.

 

인자로는 첫번째 문자열 배열, 그리고 두번쨰 문자열 배열, 그리고 비교할 인덱스 번호

 

비교한 문자열이 크거나 작으면 true or false값을 반환해서 sort를 정렬해주고 동일한 값일 경우에는 다시한번 호출하여 반복 합니다.

 

 

이렇게 진행하게 되면 간단하게!? 문자열을 임의의 순서대로 정렬할 수 있습니다.

 

 

# 3항 연산자를 사용하여 코드량은 함축한 내용

func solution(_ strings:[String], _ n:Int) -> [String] {
    
    func heap(_ first: [String.Element], _ second: [String.Element], _ index: Int) -> Bool {
        first[index] == second[index] ? heap(first, second, index + 1) : first[index] < second[index]
    }
    
    return strings.sorted { Array($0)[n] == Array($1)[n] ? heap(Array($0), Array($1), 0) : Array($0)[n] < Array($1)[n] }
}

 

# 재귀함수 대신 Swift의 내부 연산을 이용한 방법

func solution(_ strings:[String], _ n:Int) -> [String] {
    return strings.sorted { Array($0)[n] == Array($1)[n] ? $0 < $1 : Array($0)[n] < Array($1)[n] }
}

 

 

첫번째 풀이의 방법과 2번, 3번의 내용은 모두 동일하게 진행 됩니다.

반응형