C++ 如果数组长度为100000,则使用merge sort计数反转将给出一个负数

C++ 如果数组长度为100000,则使用merge sort计数反转将给出一个负数,c++,mergesort,C++,Mergesort,我还是一名编程初学者,我正在学习一门在线课程(算法) 练习题之一是在一个包含100000个随机排列的数字的文件中计算倒数。我在小数据集上尝试过这段代码,它工作得很好,但是当传递实际数据集时,它给出了负数的反转计数。尝试了不同平台的各种解决方案,但仍然无法解决 这是我的代码 #include "stdafx.h" #include <iostream>; #include <conio.h>: #include <fstream> using namespa

我还是一名编程初学者,我正在学习一门在线课程(算法)

练习题之一是在一个包含100000个随机排列的数字的文件中计算倒数。我在小数据集上尝试过这段代码,它工作得很好,但是当传递实际数据集时,它给出了负数的反转计数。尝试了不同平台的各种解决方案,但仍然无法解决

这是我的代码

#include "stdafx.h"
#include <iostream>;
#include <conio.h>:
#include <fstream> 

using namespace std;

long merge(int a[], int start, int mid, int end) 
    int i = start; 
    int j = mid + 1; 
    int k = start; 
    int inversion=0;
    int temp[100000];

    while (i <= mid && j <= end)
    {
        if (a[i] < a[j])  
        {
            temp[k++] = a[i++]; 
        }
        else 
        {
            temp[k++] = a[j++]; 
            inversion =inversion + (mid - i);
        }
    }
    while (i <= mid) 
    {
        temp[k++] = a[i++]; 
    }
    while (j <= end) 
    {
        temp[k++] = a[j++]; 
    }

    for (int i = start; i <= end; i++)
    {
        a[i] = temp[i]; 
    }
    return inversion;

long Msort(int a[], int start,int end)
{
    if (start >= end)
    {
        return 0;
    }
    int inversion = 0;
    int mid = (start + end) / 2;

    inversion += Msort(a, start, mid);
    inversion += Msort(a, mid + 1, end); 

    inversion += merge(a, start, mid, end)
    return inversion;
}

long ReadFromFile(char FileName[], int storage[],int n)
{
    int b;
    int count=0;
    ifstream get(FileName);
    if (!get)
    {
        cout << "no file found";
    }
    while (!get.eof())
    {
        get >> storage[count];
        count++;
    }
    b = count;
    return b;
}

int main()
{
    int valuescount = 0;
    int arr[100000];
    char filename[] = { "file.txt" };
    long n = sizeof(arr) / sizeof(arr[0]);
    valuescount=ReadFromFile(filename, arr,n);
    int no_Of_Inversions = Msort(arr, 0, valuescount -1);
    cout << endl << "No of inversions are" << '\t' << no_Of_Inversions <<'\t';
    cout <<endl<< "Total no of array values sorted"<< valuescount<<endl;
    system("pause");
}
`
#包括“stdafx.h”
#包括,;
#包括:
#包括
使用名称空间std;
长合并(整数a[],整数开始,整数中间,整数结束)
int i=开始;
int j=mid+1;
int k=开始;
int反转=0;
内部温度[100000];

而(i您的代码问题与输入大小没有直接关系。相反,从间接的角度来看,您发现的负值是函数
merge
的变量
inversion
溢出的结果

考虑输入大小
N=100000
的情况。如果此数字数组按降序排序,则该数组中的所有有序对都将是反转。换句话说,将有
N*(N-1)/2要计数的反转。正如您可能已经注意到的,该值略高于
无符号int
类型的界限。因此,当您尝试在int类型的变量中计数此值时,会发生溢出,导致负结果


要解决此问题,应在函数
merge
Msort
中将变量
inversion
的类型从
int
更改为
long
(还应更新函数
merge
Msort
的返回类型)当然,您也应该将
main
函数中
Msort
调用的返回值分配给
long
类型的变量。换句话说,将变量
no\u of\u Inversions
的类型也更改为long-long。

因此,临时数组被声明为100000-为什么需要大数据要可靠地工作?或者:问题产生的“实际”数据大小/范围是什么?我必须检查的实际数据集的大小是“100000”因此,为了使所有的东西就位,声明它的大小为100000。我会考虑“代码>反转/代码>溢出的可能性。如何检查这一点?当只有大的输入导致问题时,单步调试是不可选择的。您可以添加调试代码。例如,插入一个溢出检查:<代码>断言。(倒装句倒装句的意思是什么?为什么要加上
(mid-i)
to
inversion
it而不是简单的增量?尝试将
inversion
s的类型更改为
unsigned long
。通过反转,我们意味着i>j,其中i和j是存储在数组中的值。因此,每次i>j时,我们使用“merge sort”对数组进行排序时,我们将其计为反转。通过添加(中一)我们从索引值计算数组中特定no引起的总反转数J@Shamaz我的不好。您还应该更新
Msort
函数中变量
inversion
的类型,以及该函数的返回值。谢谢,它起作用了。您的观点是有效的,还需要更改数据类型变量“no_of_Inversions”的类型,该变量在主函数中存储函数“Msort”的返回值,然后在输出语句中显示反转计数。@Shamaz完全正确!除非更改
no_of_Inversions
变量的类型,否则在分配
Msort
调用
main()的返回值时会发生类似的溢出
没有任何倒置
。当我在实际数据集上测试修改后的代码时,我被答案卡住了,它给出了错误的答案,那么它应该是什么?你能帮我找出问题吗?@Shamaz这个问题是关于负值问题,我的答案解决了。没有任何额外的信息,解决了一个不清楚的问题对于理想的堆栈溢出问题来说,您的代码过于笼统。虽然说ir应该是一个单独的、更清晰的问题,包含更多信息,但您可能需要检查的是
valuescont
变量是否在所有情况下都存储了正确的值。