#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if RAND_MAX<(1u<<15)
#define getRandom (rand()+rand()/(RAND_MAX+1.0))/(RAND_MAX+1.0)
#else
#define getRandom rand()/(RAND_MAX+1.0)
#endif
void calSum(double *A,unsigned n)
{/*將比例轉為累進機率*/
unsigned i;
double sum;
for(i=1;i<n;++i)
A[i]+=A[i-1];
sum=A[n-1];
for(i=0;i<n;++i)
A[i]/=sum;
}
unsigned getRandIdx(double *A,unsigned n)
{/*依據機率,亂數取得對應的index*/
double x=getRandom;
int l,r,m;
if(A[0]>x)
return 0;
/*這邊用二分搜尋法*/
for(l=0,r=n-1;r>l+1;)
{
m=(l+r)/2;
if(A[m]>x)
r=m;
else
l=m;
}
return r;
}
int main()
{
int i,k;
double bound[]={1.3,1.5,1.2,1.1,1.0,0.9};/*加權,多奇怪的比例都可以*/
int count[]={0,0,0,0,0,0};
unsigned n=sizeof(bound)/sizeof(*bound);
srand(time(NULL));
/*將比例關係轉為累進機率*/
calSum(bound,n);
/*輸出各點數機率(理論值)*/
printf("probability in theorem:\n");
for(i=0;i<n;++i)
printf("%d\t%.2lf%%\n",i+1,(bound[i]-(i==0?0.0:bound[i-1]))*100);
/*讓使用者輸入取樣次數*/
printf("\ninput number of sample:");
scanf(" %d",&k);
/*取樣*/
for(i=0;i<k;++i)
++count[getRandIdx(bound,n)];
/*輸出結果*/
for(i=0;i<n;++i)
printf("%d\t%.2lf%% (%d/%d)\n",i+1,(double)count[i]/k*100.0,count[i],k);
return 0;
}