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