import java.util.ArrayList;
import java.util.Arrays;
public class WhichData
{
public int[] bestVariance(int[] sampleData, int varNum, int varDen) {
Arrays.sort(sampleData);
int sdLen = sampleData.length;
double var = (double)varNum/varDen;
double closest = 10001;
int[] res = new int[0];
for (int i = 1; i < Math.pow(2,sdLen); i++) {
double sum = 0.0;
double sumOfSquares = 0.0;
ArrayList<Integer> ss = new ArrayList<Integer>();
for (int j = i, k = 0; j > 0; j = j>>1,k++) {
if ((j&1) == 1) {
sum += sampleData[k];
sumOfSquares += sampleData[k]*sampleData[k];
ss.add(sampleData[k]);
}
}
double ssLen = ss.size();
double svar = sumOfSquares/ssLen - (sum*sum)/(ssLen*ssLen);
if (Math.abs(var-svar)==closest || Math.abs(Math.abs(var-svar)-closest)<=1e-9) {
boolean flag = false;
int len = (res.length < ss.size()) ? res.length : ss.size();
for (int j = 0; j < len; j++) {
if (res[j] < ss.get(j)) break;
else if (res[j] > ss.get(j)) {flag = true; break;}
}
if (flag) {
res = new int[ss.size()];
for (int j = 0; j < ss.size(); j++)
res[j] = ss.get(j);
}
}
else if (Math.abs(var-svar) < closest) {
closest = Math.abs(var-svar);
res = new int[ss.size()];
for (int j = 0; j < ss.size(); j++)
res[j] = ss.get(j);
}
}
return res;
}
}
Explanation
- bit mask와 재귀를 사용하여 푸는 두 가지 방법이 있다. 재귀가 더 빠르지만 bit mask를 사용해 문제를 풀었다.
- 더블 자료형의 정밀도(1e-9)를 검사하는 if문을 먼저 넣어줘야 한다. 실제 계산에서는 똑같은 분산이지만, 컴퓨터 계산에서는 정밀도로 인해 뒤바뀔 수 있기 때문이다.
- 분산 계산 중 공통된 부분을 줄여서 계산했다. 참조한 사이트에 계산법이 나와 있다.
References
최근 덧글