이 방법 신박하네요. ㅋㅋ
비교가 추가되기 때문에 시간이 쪼금 더 걸리지만, (0.4sec vs 0.5sec)
그걸 무시할 수 있을 정도로 메모리 절약이 엄청나니, (400mb vs 12mb)
이 방법이 더 낫겠네요. 이번에도 볼포에서 많이 배웁니다. ㅎㅎ
1바이트에 8개의 비트가 있으므로 100000000 개의 참/거짓 값을 100000000 /8=12500000 개의 변수(1바이트)로 표현 가능합니다.
즉 1바이트 변수 하나로 8개의 참/거짓을 저장 할 수 있다는 거죠.
00000001=1;
00000010=2;
00000100=4;
00001000=8;
...
10000000=2^7;
만약 1바이트 변수값이 3이라면 2진수로 00000011 이므로
6개의 거짓값과 두 개의 참 값이 저장되어 있다고 할 수 있습니다.
이런건 해보지 않고는 손이 근질거려서 못참기에 구현한 예제를 올립니다.
struct PHONENUMBER {
short f,r;
AnsiString GetNumber() {
AnsiString s;
s.printf("010-%04d-%04d",f,r);
return s;
}
};
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime N=Now();
char *a = new char[100000000/8];
memset(a,0,sizeof(char)*100000000/8);
int num,idx,bit;
// 010-0000-0000
// 010-0000-0001
// 010-0001-0000 을 뽑지 않도록 미리 해당 비트를 1로 채움
a[0]=3;
num=10000;
idx=num/8;
bit=num%8;
a[idx]|=(int)pow(2,bit);
int ExtractionCount=400000;
int Extracted=0;
PHONENUMBER *result=new PHONENUMBER[ExtractionCount];
randomize();
while(Extracted<ExtractionCount) {
num=random(100000000);
idx=num/8;
bit=num%8;
if (!a[idx]&(int)pow(2,bit)) {
a[idx]|=(int)pow(2,bit);
result[Extracted].f=num/10000;
result[Extracted].r=num%10000;
Extracted++;
}
}
N=Now()-N;
ShowMessage(N.FormatString("s.zzz"));
for (int i = 0; i < Extracted; i++) {
Memo1->Lines->Add(result[i].GetNumber());
}
delete[] a;
delete[] result;
}
//---------------------------------------------------------------------------
|