programmers 시저 암호
문제에 제시한 그대로 풀면 되는 문제라 크게 어려움은 없었지만 문제 해결에 있어 좀 더 나은 방법을 발견하게 되어서 기록하려고 합니다.
이 문제의 경우 (대문자, 소문자, 공백) 이렇게 3가지를 고려하면 되는데요. 이 비교하는 방법에 있어서 여러 방법이 있습니다. 우선 첫번째 제가 사용했던 경우입니다.
class Solution {
public String solution(String s, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char target = s.charAt(i);
if(target >= 65 && target <= 90) sb.append((char)((target - 65 + n) % 26 + 65));
if(target >= 97 && target <= 122) sb.append((char)((target - 97 + n) % 26 + 97));
if(target == 32) sb.append(target);
}
return sb.toString();
}
}
저의 경우 아스키코드값으로 조건문 안에서 그대로 활용하고 있습니다. 65('A'), 90('Z'), 97('a'), 122('z') 값은 제가 출력해보면서 알았는데요. 굳이 저렇게 할 필요가 없습니다. 그냥 'A'나 'Z'를 그대로 써주면 아스키코드값으로 인식하거든요.
class Solution {
public String solution(String s, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char target = s.charAt(i);
if(target >= 'A' && target <= 'Z') sb.append((char)((target - 'A' + n) % 26 + 'A'));
if(target >= 'a' && target <= 'z') sb.append((char)((target - 'a' + n) % 26 + 'a'));
if(target == ' ') sb.append(target);
}
return sb.toString();
}
}
이 상태에서 좀 더 나아가 Java API에서 제공하는 기능을 이용하면 더욱 쉽습니다. Character
클래스 내에 isUpperCase()
, isLowerCase()
를 이용하는 것입니다. 또 문제에서 대문자, 소문자, 공백 밖에 없다고 했으니 else if 처리하여 마지막 공백의 경우 비교를 굳이 안해도 되죠.
class Solution {
public String solution(String s, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char target = s.charAt(i);
if(Character.isLowerCase(target)) {
sb.append((char)((target - 'a' + n) % 26 + 'a'));
} else
if(Character.isUpperCase(target)) sb.append((char)((target - 'A' + n) % 26 + 'A'));
else
sb.append(target);
}
return sb.toString();
}
}
이렇게 바꾸면 코드의 의미를 훨씬 명확하게 전달하면서 간단하게 문제를 해결할 수 있네요!
programmers 약수의 합
오늘 푸는 문제는 직관적인 문제가 많네요! 그래서 이번 문제는 Java의 Stream을 이용하여 한 줄로 끝내기를 도전했습니다. 몇 번의 검색결과 완성했어요!!
class Solution {
public int solution(int n) {
return IntStream.range(1, n / 2 + 1)
.boxed()
.filter(i -> n % i == 0)
.mapToInt(Integer::intValue)
.sum() + n;
}
}
우선 range의 범위를 1부터 n / 2 + 1
까지 했는데요. 그 이유는 약수의 특성상 절반까지 탐색하고 그 이후는 자기 자신만 약수이기 때문입니다(사실 전 처음엔 n까지 다 탐색했어요..)
이제는 한 줄씩 어떤 역할을 가진 메서드인지 알아봅시다.
IntStream
은 Oracle Docs에서 다음과 같이 설명하고 있네요.
A sequence of primitive int-valued elements supporting sequential and parallel aggregate operations. This is the
int
primitive specialization ofStream
.
원시 자료형 int
의 연속적인 값들의 전체 연산을 위한 것이니 완벽하네요.
boxed()
는 무엇을 의미할까요?
Returns a
Stream
consisting of the elements of this stream, each boxed to anInteger
.
Intellij에서 Stream을 사용하면 명시적으로 어떤 타입을 가지고 있는지 가르쳐주는데요. IntStream.range()
을 연산하면 Intstream
을 가집니다. 이 상태에서 boxed()
하면 Stream<Integer>
타입으로 바뀌는데요. Integer
타입을 Stream
형태로 담고 있는 것이죠.
- 이렇게
Stream<Integer>
타입으로 바뀌면filter()
를 통해 약수를 골라냅니다. mapToInt(Integer::intValue)
는mapToInt(i -> i.intValue())
와 같은데요.Integer
타입을int
값으로 바꿔줍니다.- 이후에 다시
IntStream
으로 타입이 바뀌었네요.sum()
을 통해 담겨진 수를 모두 더합니다. - 마지막의 + n 은 자기 자신도 약수니까 더하는거구요!
Intellij의 도움을 받아 Stream형을 다 풀면 다음과 같습니다.
class Solution {
public int solution(int n) {
int sum = 0;
int bound = n / 2 + 1;
for (int i = 1; i < bound; i++) {
Integer integer = i;
if (n % integer == 0) {
int intValue = integer.intValue();
sum += intValue;
}
}
return sum + n;
}
}
'Algorithm > problem solving' 카테고리의 다른 글
Today's Algorithm(2018-11-10) (0) | 2018.11.10 |
---|---|
Today's Algorithm(2018-11-09) (0) | 2018.11.09 |
Today's Algorithm(2018-11-05) (0) | 2018.11.05 |
Today's Algorithm(2018-11-04) (0) | 2018.11.04 |
Today's Algorithm(2018-11-01) (0) | 2018.11.01 |