st = new StringTokenizer(br.readLine(), " ");
은 무엇인가?
StringTokenizer는 문자열을 특정 구분자를 기준으로 여러 토큰으로 분리하는 데 사용되는 Java의 클래스입니다 1.nextToken() 메서드는 StringTokenizer의 다음 토큰을 반환합니다 1.
아래는 StringTokenizer와 .nextToken() 메서드를 사용하는 과정
"1 2 3 1 2" -> StringTokenizer -> "1", "2", "3", "1", "2"
이제, 이 과정을 자바 코드로 표현해 보겠습니다:
Java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
}
위의 코드에서,
BufferedReader는 사용자로부터 입력을 받습니다1StringTokenizer는 이 입력을 공백을 기준으로 토큰으로 분리합니다 1. 그런 다음,. nextToken() 메서드를 사용하여 각 토큰을 순서대로 출력합니다 1.
이 코드를 실행하면, 사용자가 "1 2 3 1 2"라는 문자열을 입력하면, 다음과 같은 출력을 얻을 수 있습니다:
1
2
3
1
2
이렇게 StringTokenizer와 .nextToken() 메서드를 사용하면,
문자열을 토큰 단위로 분리하고, 이를 순차적으로 처리할 수 있습니다1.
이는 사용자로부터 여러 값을 한 번에 입력받는 경우에 유용하게 사용될 수 있습니다 1.
StringTokenizer의 생성자에 입력받은 문자열 line과 구분자 " "를 넘겨줌으로써,
StringTokenizer는 line을 " " 기준으로 토큰으로 나눕니다.
즉, 사용자가 입력한 "1 2 3 1 2"라는 문자열은 StringTokenizer에 의해 "1", "2", "3", "1", "2"라는 토큰으로 분리됩니다.
그리고 nextToken() 메서드를 호출하면, 이 토큰들을 차례대로 가져올 수 있습니다.
이렇게 StringTokenizer는 문자열을 주어진 구분자를 기준으로 토큰으로 나누는 역할을 수행하며, nextToken() 메소드를 통해 이 토큰들을 하나씩 읽어올 수 있습니다.
long result = 0; // 결괏값
for (int i = 0; i < M; i++) {
if (acc [i] >= 2) {
result += (acc[i] * (acc[i] - 1)) / 2;
}
}
은 무엇일까?
remainderCount 배열을 순회하는 부분은 이렇게 작동합니다:
remainderCount 배열의 인덱스 i를 0부터 M-1까지 순회를 시작합니다. 이때 i는 누적 합의 나머지 값입니다.
java
for (int i = 0; i < M; i++) {
각 인덱스 i에 대해, remainderCount [i]의 값이 2 이상인지 확인합니다.
remainderCount[i]의 값이 2 이상이라는 것은 누적합의 나머지가 i인 경우가 2번 이상 발생했다는 의미입니다.
java
if (remainderCount[i] >= 2) {
만약 remainderCount[i]의 값이 2 이상이라면, 이 값 중 2개를 선택하는 조합의 수를 계산합니다. 이는 (remainderCount [i] * (remainderCount[i] - 1)) / 2로 계산할 수 있으며, 이 값은 countCombination에 저장됩니다.
java
long countCombination = (remainderCount[i] * (remainderCount[i] - 1)) / 2;
계산한 조합의 수 countCombination을 numSubsequences에 더합니다.
이는 누적합의 나머지가 같은 경우의 수를 모두 더하는 과정입니다.
java
numSubsequences = numSubsequences + countCombination;
위의 과정을 i가 M-1이 될 때까지 반복합니다.
마지막으로, numSubsequences를 출력합니다. 이는 누적합의 나머지가 같은 경우의 수의 총합입니다.
java
System.out.println(numSubsequences);
이렇게 remainderCount 배열을 순회하면서, 누적합의 나머지가 같은 경우의 수를 계산하게 됩니다.
/2라는 것은 '조합'을 뜻한다?? 수학?
"/2"는 조합의 개수를 계산하는 공식에서 나옵니다.
이는 수학에서 조합(Combination)을 계산하는 공식인 n*(n-1)/2를 따르는 것입니다.
조합이란,
주어진 집합에서 일부를 선택하는 방법의 수를 말합니다.
여기서 n*(n-1)/2는, n개의 원소 중에서 2개를 선택하는 조합의 개수를 계산하는 공식입니다.
예를 들어, 3개의 원소 중에서 2개를 선택하는 조합의 개수는 (3*2)/2 = 3이 됩니다.
따라서, 이 코드에서 "/2"는 주어진 나머지 값에 해당하는 요소 중에서 2개를 선택하는 방법의 수, 즉 조합의 개수를 계산하기 위한 것입니다. 이를 통해 누적합이 M으로 나누어 떨어지는 부분 수열의 개수를 찾을 수 있습니다.
조합의 공식이란? ( 원소의 조합을 구하는 수학 공식 = n*(n-1)/2 )
조합은 주어진 집합에서 일부를 선택하는 방법의 수를 찾는 것을 의미합니다.
이는 순서를 고려하지 않고, 단지 선택된 요소들 자체에만 중점을 둡니다.
예를 들어, 3개의 원소 {A, B, C}가 있을 때, 이 원소들 중에서 2개를 선택하는 조합은
다음과 같이 3가지 경우가 있습니다:
{A, B}, {A, C}, {B, C}.
이렇게 조합의 개수를 계산하는 공식은 n*(n-1)/2입니다.
이는 n개의 원소 중에서 2개를 선택하는 경우의 수를 의미합니다.
싱글톤 패턴에 대해
싱글톤 패턴에 대해 간단하게 설명드리겠습니다.
싱글톤 패턴은 특정 클래스의 인스턴스가 하나만 만들어지고, 그 인스턴스에 대해 전역적으로 접근할 수 있도록 하는 디자인 패턴입니다.
예를 들어, 데이터베이스 연결 객체를 여러 개 만들면 자원을 낭비하게 됩니다. 이런 경우에 싱글톤 패턴을 사용하면 하나의 객체만 만들고 그 객체를 재사용할 수 있습니다.
아래에 싱글톤 패턴을 구현한 간단한 자바 코드를 보여드리겠습니다.
java
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
위 코드에서 Singleton 클래스는 private 생성자를 가지며, 이 클래스의 인스턴스는
getInstance() 메서드를 통해서만 얻을 수 있습니다.
처음 getInstance()가 호출되면 uniqueInstance는 null이므로 새로운 Singleton 인스턴스를 생성하고,
그 이후로는 항상 이렇게 생성된 인스턴스를 반환합니다.
이 방식으로 인해 Singleton 클래스의 인스턴스는 하나만 생성되게 됩니다.
이렇게 싱글톤 패턴을 사용하면, 동일한 자원에 대한 동시 요청을 효과적으로 관리할 수 있습니다.
아래는 이 코드가 어떻게 작동하는지를 도식화한 그림입니다.
1. getInstance() 호출 -> uniqueInstance 확인
2. uniqueInstance 가 null 이면 -> new Singleton()을 통해 인스턴스 생성
3. uniqueInstance 가 null 이 아니면 -> 이미 생성된 uniqueInstance 반환
이처럼 싱글톤 패턴을 사용하면, 동일한 자원에 대한 동시 요청을 효과적으로 관리할 수 있습니다.
하지만 멀 티쓰레딩 환경에서는 동기화 문제를 주의해야 합니다.
자바에서는 synchronized 키워드를 통해 이를 해결할 수 있습니다.
싱글톤 프라이빗 퍼블릭의 차이점
이 코드에서 private과 public 키워드는 각각 클래스 내부에서만 접근이 가능하도록 하거나 외부에서도 접근이 가능하도록 하는 역할을 합니다.
먼저, Singleton 클래스의 생성자는 private로 선언되어 있습니다.
이는 Singleton 클래스 외부에서는 new Singleton()과 같은 방식으로 인스턴스를 생성할 수 없게 만듭니다.
대신,
getInstance()라는 public 메서드를 통해 인스턴스를 얻을 수 있습니다.
getInstance() 메서드는 public으로 선언되어 있으므로 이 메소드는 외부에서 접근이 가능합니다.
이 메서드를 통해 Singleton 인스턴스를 얻을 수 있으며, 이 메서드는 항상 동일한 Singleton 인스턴스를 반환합니다.
따라서 이 코드에서는 private 생성자를 통해 외부에서 Singleton 클래스의 인스턴스를 임의로 생성하는 것을 막고, public 메서드인 getInstance()를 통해 항상 동일한 인스턴스를 얻을 수 있도록 하여 싱글톤 패턴을 구현하고 있습니다.
이렇게 하면 Singleton 클래스의 인스턴스가 단 하나만 생성되고, 그 인스턴스를 여러 곳에서 공유하여 사용할 수 있게 됩니다.
이는 싱글톤 패턴의 주요 목적인 "특정 클래스의 인스턴스가 하나만 만들어지고, 그 인스턴스에 대한 전역 접근을 제공"하는 것을 가능하게 합니다.
1. 외부에서 Singleton.getInstance() 호출
|
V
2. getInstance() 메소드 내부에서 uniqueInstance가 null인지 확인
|
V
3. uniqueInstance가 null이면, new Singleton()을 통해 Singleton 인스턴스 생성
|
V
4. uniqueInstance를 반환 (이제 외부에서는 이 uniqueInstance를 통해 Singleton 인스턴스에 접근 가능)
'컴퓨터공부 > 책리뷰 & book review' 카테고리의 다른 글
Do it! 알고리즘 입문: 자바 편 (28)[책리뷰 & Book review] (1) | 2024.02.06 |
---|---|
Do it! 알고리즘 입문: 자바 편 (27)[책리뷰 & Book review] (0) | 2024.02.06 |
Do it! 알고리즘 입문: 자바 편 (25)[책리뷰 & Book review] (0) | 2024.02.05 |
Do it! 알고리즘 입문: 자바 편 (24)[책리뷰 & Book review] (1) | 2024.02.05 |
댓글