Attualmente sto lavorando all'esercizio del conteggio delle inversioni usando mergesort. Il problema che sto affrontando è quando ho array di piccole o medie dimensioni, il risultato è perfettamente soddisfacente, tuttavia se utilizzo un testcase molto grande (una matrice di 100.000 interi) non mi dà il numero corretto di inversioni. Non ho idea di come mai sta succedendo. Qui è il mio codice:Inversioni di conteggio (numero con input grande)
static int [] helper;
static long count=0;
static Integer [] arr3;
private static void mergeSortMethod(Integer[] arr3) {
int head=0;
int tail=arr3.length-1;
int mid=tail+((head-tail)/2);
sort(arr3,head,tail);
}
private static void sort(Integer[] arr3, int low, int high) {
if (high<=low){
return;
}
int mid=low+ ((high-low)/2);
sort(arr3,low,mid);
sort(arr3,mid+1,high);
merge3CountInvs(arr3,low,mid,high);
}
private static void merge3CountInvs(Integer[] arr3, int low, int mid, int high) {
int i=low;
int j=mid+1;
int k=low;
//to get size of first half of array
int nArr1Elems=(mid-low)+1;
for (int m=low;m<=high;m++){
helper[m]=arr3[m];
}
while(i < mid+1 && j < high+1){// neither array empty
if(helper[i] < helper[j]){
arr3[k++] = helper[i++];
}
else if (helper[j] < helper[i]){
arr3[k++] = helper[j++];
int numOFElements=nArr1Elems-i;
count=count+(nArr1Elems-i);
}
}
while(i < mid+1){ // arrayB is empty,
arr3[k++] = helper[i++];
}
while(j < high+1){ // arrayA is empty,
arr3[k++] = helper[j++];
}
}
La mia soluzione dà risposte corrette quando non si utilizza molto grandi ingressi tuttavia quando ho usato banco di prova di 100.000 interi che era il numero di inversioni che ho ricevuto:
Dalla mia realizzazione: - 30588581433
risposta corretta è: 2407905288
Tutte le idee? Gradirei qualsiasi tipo di aiuto. Grazie.
MODIFICA: Come menzionato nelle risposte sul caso di overflow intero è il punto in cui sto avendo difficoltà a capire poiché il "conteggio" delle variabili che causa l'overflow è inizializzato come "lungo", quindi non ci dovrebbero essere overflow in questo caso. Non riesco a pensare a nessuna altra variabile che possa causare un overflow di numeri interi nel mio codice. Molte grazie.
UPDATE:
Non c'era alcun problema relativo alla integer overflow, ma grazie per le risposte però la risposta di Reddy mi ha punto nella giusta direzione quindi grazie ancora una volta. L'unico errore nel mio algoritmo è stato:
int nArr1Elems=(mid-low)+1;
count=count+(nArr1Elems-i);
Quando avrebbe dovuto essere:
count=count+(mid-i+1);
Come dobbiamo sottrarre dagli elementi lasciati sul lato sinistro della serie "dopo" l'ordinamento non inizialmente quando la subroutine viene chiamata poiché l'indice cambia dopo l'ordinamento. Sto scrivendo il mio codice aggiornato nel caso in cui se qualcuno sarebbe finito in un problema simile come il mio:
static int [] helper;
static long count=0;
static Integer [] arr3;
private static void mergeSortMethod(Integer[] arr3) {
int head=0;
int tail=arr3.length-1;
int mid=tail+((head-tail)/2);
sort(arr3,head,tail);
}
private static void sort(Integer[] arr3, int low, int high) {
if (high<=low){
return;
}
int mid=low+ ((high-low)/2);
sort(arr3,low,mid);
sort(arr3,mid+1,high);
merge3CountInvs(arr3,low,mid,high);
}
private static void merge3CountInvs(Integer[] arr3, int low, int mid, int high) {
int i=low;
int j=mid+1;
int k=low;
for (int m=low;m<=high;m++){
helper[m]=arr3[m];
}
while(i < mid+1 && j < high+1){// neither array empty
if(helper[i] < helper[j]){
arr3[k++] = helper[i++];
}
else if (helper[j] < helper[i]){
arr3[k++] = helper[j++];
//to increment count with total number of elements left in arrayA after sorting
count=count+(mid-i+1);
}
}
while(i < mid+1){ // arrayB is empty,
arr3[k++] = helper[i++];
}
while(j < high+1){ // arrayA is empty,
arr3[k++] = helper[j++];
}
}
"* Gradirei qualsiasi tipo ** ** di aiuto. *" Gioco di parole? – jason
Posso vedere alcuni errori nel tuo algoritmo.per favore controlla con la mia risposta – Reddy