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

Why is this counter increasing in this way and not one by one in this divide and conquer algorithm?

本文关键字:增加 一个 算法 分而治之 计数器 方式 为什么      更新时间:2023-10-16

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

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

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