我仍然是编程的初学者,我正在上一门在线课程(算法)
其中一个练习题是计算包含随机排序的100000个数字的文件中的反转次数
所以这是我的代码
package algo_inversion;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class Algo_inversion {
public static int splitMerge(int[]A,int start,int mid,int finish){
int count=0;
int []L=new int[mid+2-start];
int []R=new int[finish-mid+1];
System.arraycopy(A, start, L, 0, L.length-1);
L[L.length-1]=5000000;//infinity
for(int i=0;i<R.length-1;i++){
R[i]=A[mid+1+i];
}
R[R.length-1]=5000000;//infinity
int x=0;
int y=0;
for(int k=start;k<finish+1;k++){
if(L[x]<=R[y]){
A[k]=L[x];
x++;
}
else{
A[k]=R[y];
y++;
count+=L.length-1-x;
}
}
return count;
}
public static int countMerge(int []A,int start, int finish){
if(finish<=start){
return 0;
}
else{
int mid=(finish+start)/2;
int leftCount=countMerge(A,start,mid);
int rightCount=countMerge(A,mid+1,finish);
int splitCount=splitMerge(A,start,mid,finish);
return(leftCount+rightCount+splitCount);
}
}
public static void main(String[] args) throws FileNotFoundException {
int []a=new int[100001];
Scanner in= new Scanner(new FileReader("IntegerArray.txt"));
int i=0;
while(in.hasNext()){
a[i]=in.nextInt();
i++;
}
in.close();
System.out.println("inversions=: "+countMerge(a, 0, i-1));
}
}
我尝试了从1到200的随机数组,它完美无缺 但是从文件中的数组它给了我一个负数!!! 我只是无法弄清楚是什么导致了这一点,并希望我能得到任何帮助 ^ _ ^
答案 0 :(得分:1)
大小为N
的数组中最坏情况的反转数为N*(N-1)/2
。适合int的最高值约为20亿,因此大小超过65,000
的数组可能会溢出int
,从而使结果看起来是负面的。
您应切换到long
以扩展计数器可表示的值范围:
public static long splitMerge(int[]A,int start,int mid,int finish) {
long count = 0;
...
}
public static long countMerge(int []A,int start, int finish) {
...
}
答案 1 :(得分:1)
我在大小从1到200的随机数组上尝试过,它运行得很好但是从文件中的数组它给了我一个负数!!!
反转次数似乎超过Integer.MAX_VALUE
的值,因此您看到溢出为负数;您应该使用long
来计算反转次数。
这是Joel Spolsky的The Perils of JavaSchools的一个例子。通过将人们隐藏在机器中真正存在的东西中,当他们遇到这样的问题时,他们不知道发生了什么。当你计算一些东西,并且你看到负面结果时,应该突然出现的第一个事物是溢出的,超出了Integer.MAX_VALUE
的界限。