View
입력
첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.
출력
각 테스트케이스마다 A+B를 한 줄에 하나씩 순서대로 출력한다.
문제는 그렇게 어렵지 않다. 그러나 이 문제를 가져와 글을 쓰는 이유는 이런 조건이 달려있어서 이다.
“입출력 방식이 느리면 여러 줄을 입력받거나 출력할 때 시간초과가 날 수 있다. 입출력을 더 빠르게 할 수 있는 방식을 찾아 사용하자.” (라고 정리할 수 있겠다)"
그리고 각 언어별로 속도를 올릴 수 있는 방법을 코멘트로 적어두었는데, C#은 아래와 같이 적혀있었다.
C#
StreamReader로 읽고, StringBuilder로 출력을 모아 놓았다가 그 String을 Console.WriteLine하는 방법이 있습니다. BufferedStream과 StringWriter로 조금 더 향상시킬 수 있는 것 같으나 자세한 것은 다른 분의 답변을 기다리겠습니다.
이에 따라 StringBuilder에 대해 찾아보았다.
StringBuilder
StringBuilder는 System.Text 네임스페이스에 속해있다.
String과 StringBuilder 둘 다 문자열을 표현하기위해 사용되지만, 다르게 구현된다.
String은 변경할 수 없는 데이터이다. String 개체를 수정할때는 원래 저장된 문자열과 다른 새로운 문자열을 만들어 주소를 전달한다.
문자열을 변경하는 경우가 적은 경우, 고정된 문자열을 사용하는 경우, 문자열에서 검색을 해야하는 경우에는 String을 쓰는 것이 성능에 도움이 된다.
StringBuilder는 String과 다르게 추가, 제거, 바꾸기, 삽입 등의 문자열 수정이 가능하다. 초기에 설정된 메모리의 최대 크기를 벗어나면 메모리공간을 2배로 늘이는 식으로 동적으로 관리한다.
사용자가 입력을 하면 문자열을 변경해야하는 경우, 문자열이 자주 바뀌는 경우에는 StringBuilder를 이용하는 것이 더 좋다. 메모리의 양, 문자열의 크기에 따라 성능이 달라지기 때문에, StringBuilder를 이용하는 것이 무조건적인 성능향상을 이끌어내지는 않으므로, 성능 향상의 여부를 확인하고 사용해야 한다.
Append(), Insert(), Clear(), Remove(), Replace() 등의 메서드를 사용하여 문자열을 조작할 수 있다.
백준 문제에 대한 나의 코드는 다음과 같다.
원래같았으면 계속 string을 바꾸면서 문자열을 출력했겠지만, 성능향상을 위해 StringBuilder를 사용해주었다. StringBuilder에서 값을 저장하는데, 한 문장을 저장하고 개행문자를 넣는 식으로 쭉 Append를 해서 맨 마지막에 모든 줄을 출력하도록 만들어주었다.
using System;
using System.Text;
class MainClass {
public static void Main (string[] args) {
StringBuilder sb = new StringBuilder();
string[] data;
int maxCase = int.Parse(Console.ReadLine());
for (int i = 0; i < maxCase; i++) {
data=Console.ReadLine().Split();
sb.Append(int.Parse(data[0])+int.Parse(data[1]) + "\n");
}
Console.WriteLine(sb);
}
}
Today I Learned
String은 Value가 아닌 Ref. 값을 수정할 수 없다. String의 값을 수정하는 작업은 새로운 String Class를 만들어 문자열을 새로 넣어준 다음 전달하는 과정을 거치며, 남겨진 원래 String 데이터는 GC에 의해 수집될 때 까지 잔류한다. 계속 바뀌는 문자열을 String 으로 다루는 방법은 그리 효율적이지 않다.
StringBuilder는 String을 새로 인스턴트를 만들지 않고서도 수정할 수 있는 메서드를 갖고있다. 시간이나 메모리에 좀 더 효율적인 방식이다.
'Develop > 알고리즘' 카테고리의 다른 글
[백준] 2352 - 반도체 설계 (0) | 2021.08.09 |
---|---|
[백준] 1072 - 게임 (0) | 2021.08.09 |
[백준] 12015 - 가장 긴 증가하는 부분 수열 2 (0) | 2021.08.09 |
[백준] 4344번, C# Write( ), WriteLine( ) 메서드에서 format 지정해주기 (0) | 2020.07.22 |
C#으로 알고리즘 시작 (0) | 2020.07.18 |