我正在阅读以下问题的算法解决方案:
此文件按某种顺序包含1到100,000(含)之间的所有100,000个整数,不重复整数。 您的任务是计算给定文件中的反转次数,其中文件的第i行表示数组的第i个条目。 由于此阵列的大小,您应该实现视频讲座中涵盖的快速分而治之算法。 应在下面的空白处输入给定输入文件的数字答案。
所以问题会给你文件,但这是解决方案:
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#define SIZE 100000
using namespace std;
long long splitInv(long *arr, long l, long u)
{
long *tarr = new long[u-l+2];
long i=l, j=(u-l)/2+l+1, k;
long long count=0;
for(k=1; (k<=u-l+1) && (i<=(u-l)/2+l) && (j<=u); k++)
{
if(arr[i]<arr[j]) tarr[k]=arr[i++];
else
{
tarr[k]=arr[j++];
count=count+((u-l)/2+l-i+1);
}
}
for(; k<=u-l+1 && i<=(u-l)/2+l; k++) tarr[k]=arr[i++];
for(; k<=u-l+1 && j<=u; k++) tarr[k]=arr[j++];
for(k=1, i=l ; k<=u-l+1 && i<=u; k++, i++) arr[i]=tarr[k];
delete tarr;
return count;
}
long long numInv(long *arr, long l, long u)
{
if(u<=l) return 0;
return numInv(arr, l, (u-l)/2+l) + numInv(arr, (u-l)/2+l+1, u) + splitInv(arr, l, u);
}
int main(int argc, char *argv[])
{
long *arr=new long[SIZE+1];
char a[10];
FILE *f=fopen("IntegerArray.txt","r");
for(long i=1; i<=SIZE; i++)
{
fgets(a,10,f);
arr[i]=atol(a);
}
fclose(f);
cout<<"Number of Inversions: "<<numInv(arr,1,SIZE)<<endl;
delete arr;
system("PAUSE");
return EXIT_SUCCESS;
}
所以,我很想知道为什么计数器通过以下方式而不是一个接一个地增加,因为它只是计算反转次数:
count=count+((u-l)/2+l-i+1);
所以,对我来说应该是:
count=count+1;
答案 0 :(得分:0)
如你所知它正在使用分而治之算法,如果if条件不正确,则需要忽略前半部分,因此它必须如程序中所示偏移数组,而不是像你想象的那样。