为什么这个计数器会以这种方式增加,而不是在这种分而治之的算法中逐一增加?

时间:2015-01-31 13:51:14

标签: c++ algorithm divide-and-conquer

我正在阅读以下问题的算法解决方案:

  

此文件按某种顺序包含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;

1 个答案:

答案 0 :(得分:0)

如你所知它正在使用分而治之算法,如果if条件不正确,则需要忽略前半部分,因此它必须如程序中所示偏移数组,而不是像你想象的那样。