Java:计数反转算法逻辑出错
我正在尝试编写计数反转算法。它适用于大小为10的数组。然而,当我试图在一个大小为100000的数组上进行测试时,情况变得非常糟糕。我仍然能够对数组进行排序,但反转数为负数,这是错误的。我不明白我的逻辑哪一部分出错了 我的主要逻辑是:我创建了一个名为myArray的数组对象,它有一个CountSplitInv实例方法,假设该方法可以对子数组进行排序,并返回所涉及的反转数 请帮帮我。我已经被困在这里面很长时间了,但我仍然无法找出哪里出了问题 我有一种感觉,我不完全理解递归的概念Java:计数反转算法逻辑出错,java,algorithm,Java,Algorithm,我正在尝试编写计数反转算法。它适用于大小为10的数组。然而,当我试图在一个大小为100000的数组上进行测试时,情况变得非常糟糕。我仍然能够对数组进行排序,但反转数为负数,这是错误的。我不明白我的逻辑哪一部分出错了 我的主要逻辑是:我创建了一个名为myArray的数组对象,它有一个CountSplitInv实例方法,假设该方法可以对子数组进行排序,并返回所涉及的反转数 请帮帮我。我已经被困在这里面很长时间了,但我仍然无法找出哪里出了问题 我有一种感觉,我不完全理解递归的概念 import jav
import java.io.*;
import java.util.*;
import java.math.*;
class myArray{
private int[] input_array;
private int nElems;
public myArray(int max){
input_array = new int[max];
nElems = 0;
}
public void insert(int value){
input_array[nElems++] = value;
}
public void display(){
for(int j = 0; j < nElems; j++){
System.out.print(input_array[j] + " ");
}
System.out.println("");
}
public void SortAndCount(){
int[] output_array = new int[nElems];
int ans = SortNInversionCounts(output_array,0, nElems -1);
System.out.println("number of inversions IS: " + ans);
}
public int SortNInversionCounts(int[] output_array, int lowerBound, int upperBound){
if(lowerBound == upperBound){
return 0;
} else{
int mid = (lowerBound + upperBound)/2;
int x, y , z;
x = SortNInversionCounts(output_array, lowerBound, mid);
y = SortNInversionCounts(output_array, mid+1, upperBound);
z = CountSplitInv(output_array, lowerBound, mid+1, upperBound);
return x + y + z;
}
}
public int CountSplitInv(int[] output_array, int lowPtr, int highPtr, int upperBound){
int j = 0;
int lowerBound = lowPtr;
int mid = highPtr - 1;
int n = upperBound - lowerBound + 1;
int numOfInversions = 0;
while(lowPtr <= mid && highPtr <= upperBound){
if( input_array[lowPtr] < input_array[highPtr]){
output_array[j++] = input_array[lowPtr++];
} else{
output_array[j++] = input_array[highPtr++];
// WHERE I count number of inversions
numOfInversions = numOfInversions + (mid - lowPtr + 1);
}
}
while(lowPtr <= mid){
output_array[j++] = input_array[lowPtr++];
}
while(highPtr <= upperBound){
output_array[j++] = input_array[highPtr++];
}
for(j = 0; j < n; j++){
input_array[lowerBound+j] = output_array[j];
}
return numOfInversions;
}
}
class NumOfInversionsApp{
public static void main(String[] args) throws IOException{
// Read input file
FileInputStream fil = new FileInputStream("IntegerArray.txt");
BufferedReader br = new BufferedReader( new InputStreamReader(fil));
myArray in_array = new myArray(100000);
String element = null;
while( ( element = br.readLine()) != null){
in_array.insert( Integer.parseInt(element) );
}
// input_array.display();
in_array.SortAndCount();
// input_array.display();
}
}
我找不到任何明显错误的东西。然而,一个100000的数组可能会有太多的反转,无法容纳在一个it中。也许试着用long来代替?天哪,你是对的,一切都很好,一旦我做了long的numOfInversions而不是int的numOfInversions。但为什么会这样?我不明白。32位整数可以容纳的最大值是2^31-1。如果你超出这个范围,那么一些被称为溢出的事情就会发生。例如,假设我们只有4位,而不是32位。所以最大值是2^3-1=7=0111二进制,如果我们加1,我们得到1000。请记住,最后一位是符号位,因此我们得到一个负数。本教程,即使是针对乞丐的,也对数据类型进行了很好的解释。int应该是特别感兴趣的。理解有符号和无符号int的知识可能也会有所帮助。我认为在运行时没有溢出检查,这意味着它不能抱怨。Java并不是完全面向对象的,int和long都是基本数据类型——仅仅是一个恰好代表一个数字的字节序列。然而,在大多数情况下,溢出不会发生,但即使更改为long也不会给您提供无限的数字池。如果我没有弄错的话,BigInteger可以是任意精度的,并且不会受到溢出的影响-以创建对象、分派方法等的性能为代价。。。。