import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.Stopwatch;
import java.util.Arrays;
public class E1_4_8 {
public static void main(String[]args){
//先测试结果是否一致
int[] a=new int[10000];
for (int i=0;i<10000;i++)
a[i]=StdRandom.uniform(-1000000,1000000);
StdOut.printf("TwoIntEqual result is : %d\n",TwoIntEqual(a));
StdOut.printf("TwoIntEqualFast result is : %d\n",TwoIntEqualFast(a));
//分别使用DoublingRatio的思想测试速度
int N=125;
double[] prev=timeTrial(N);
for (N=250;true;N+=N){
double[] cur=timeTrial(N);
StdOut.printf("Usual : N=%6d, time=%7.1f, ratio=%5.1f Fast : N=%6d, time=%7.1f, ratio=%5.1f\n",
N,cur[0],cur[0]/prev[0],N,cur[1],cur[1]/prev[1]);
prev=cur;
}
}
public static double[] timeTrial(int N){
double[]res=new double[2];
int[]a=new int[N];
int MAX=1000000;
for (int i=0;i<N;i++)
a[i]= StdRandom.uniform(-MAX,MAX);
Stopwatch time=new Stopwatch();
int cnt=TwoIntEqual(a);
res[0]=time.elapsedTime();
time=new Stopwatch();
cnt=TwoIntEqualFast(a);
res[1]=time.elapsedTime();
return res;
}
public static int TwoIntEqual(int[] a){
//quadratic
int N=a.length;
int cnt=0;
for (int i=0;i<N;i++)
for (int j=i+1;j<N;j++)
if (a[i]==a[j])
cnt++;
return cnt;
}
public static int TwoIntEqualFast(int[]a){
//linearithmic
Arrays.sort(a);
int cnt=0;
int N=a.length;
for (int i=0;i<N-1;i++){
int j=i+1;
while (j<N&&a[i]==a[j]){
cnt++;
j++;
}
}
return cnt;
}
public class StopWatch {
private final long start;
public StopWatch(){
start=System.currentTimeMillis();
}
public double elapsedTime(){
long now=System.currentTimeMillis();
return (now-start)/1000.0;
}
}
}