1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <string> #include <vector> using namespace std; long solution(string arrangement) { long answer = 0; long lineCount = 0; for(int i = 0; i < arrangement.length(); i++) { if(arrangement[i] == '(') { lineCount++; } else { if(arrangement[i - 1] == '(') { lineCount--; answer += lineCount; } else { lineCount--; answer += 1; } } } return answer; } | cs |
문제를 풀기 위해서 먼저 알아야 할 것은 어떻게 레이저와 쇠 막대기를 구분할 것이냐이다. 이 방법은 '(' 이것 바로 다음에 ')'이 나오면 그것은 레이저라고 판단을 하면 된다. 그 이유는 문제에 보면 쇠막대기 하나당 적어도 하나의 레이저는 가지고 있다고 나와있기 때문이다. 그래서 이것을 바탕으로 프로그래밍을 하면 위와 같이 나온다.
위의 코드를 분석해보자. 처음에 string값으로 변수 arrangement를 받았다. 이제 이 arrangement라는 변수로 위에 설명한대로 레이저인지 쇠막대기인지 파악을 한다. 반복문 안에 처음 if문을 보면 '('가 나오면 lineCount를 하나 증가시키고 있다. 그 이유는 그것이 쇠막대기의 처음이라고 생각하기 때문이다.
하지만 여기서 고려해야할 점이 쇠막대기뿐만 아니라 레이저도 '('로 시작을 한다는 것이다. 그래서 다음 else문 안에 if에서 그것이 레이저였을 가능성도 생각해주고있다. 여기서 하는 일은 현재 arrangement의 요소는 ')'이지만 바로 이전의 요소가 '('라면 레이저라고 생각하는 것이다. 그래서 lineCount를 하나 감소시키고 지금까지의 lineCount를 answer에 더해준다. 그 이후는 막대기가 끝나면 막대기의 숫자를 저장했던 lineCount를 하나씩 감소시키면서 answer값을 하나씩 증가시키고 있다. 그 이유는 잘려진 막대기의 오른쪽까지 생각해주기 때문이다.
참고로 스위프트로 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import Foundation func solution(_ arrangement:String) -> Int { let letters = arrangement.map() {String($0)} let length = letters.count var lineCount: Int = 0 var answer: Int = 0 for i in 0..<length { if letters[i] == "(" { lineCount += 1 } else if letters[i - 1] == "(" { lineCount -= 1 answer += lineCount } else { lineCount -= 1 answer += 1 } } return answer } | cs |
스위프트에서는 string값의 인덱스를 참조하려면 매우 복잡하다. 그래서 일반 c++과 같이 우리가 알고있는 배열의 인덱스를 참조하는 것처럼 만들어주기 위해서 map을 이용한다. string변수에 .map() {String($0)} 이렇게 해주면 스트링 배열로 만들어줘서 간단하게 쓸 수 있다.