Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 无效的指针操作;递归合并排序_Delphi_Recursion_Mergesort_Delphi Xe - Fatal编程技术网

Delphi 无效的指针操作;递归合并排序

Delphi 无效的指针操作;递归合并排序,delphi,recursion,mergesort,delphi-xe,Delphi,Recursion,Mergesort,Delphi Xe,我试图实现字符串的合并排序,但是我无法执行递归部分,并且出现错误“指针操作无效” 程序项目1; {$APPTYPE控制台} 使用 SysUtils; varⅠ:整数; const MyArray:string=('hi','zebra','apple','Xylophone','dog')的数组[1..5]; 过程合并(结果、左、右:字符串数组); 变量i,i1,i2:整数; 开始 i1:=0; i2:=0; 对于i:=0到长度(结果)do 开始 如果(i2>=Length(right))或(i

我试图实现字符串的合并排序,但是我无法执行递归部分,并且出现错误“指针操作无效”

程序项目1;
{$APPTYPE控制台}
使用
SysUtils;
varⅠ:整数;
const MyArray:string=('hi','zebra','apple','Xylophone','dog')的数组[1..5];
过程合并(结果、左、右:字符串数组);
变量i,i1,i2:整数;
开始
i1:=0;
i2:=0;
对于i:=0到长度(结果)do
开始
如果(i2>=Length(right))或(i1=2),则
开始
设置长度(左,长度(原始列表)第2部分);
setlength(右,长度(原始列表)-(长度(原始列表)第2部分));
对于i:=0到长度(左)do
开始
左[i]:=原作者[i];
结束;
对于i:=0到长度(右)do
开始
右[i]:=原始列表[i+长度(原始列表)div 2];
结束;
合并排序(左);
合并排序(右);
合并(原始列表、左、右);
结束;
结束;
开始
writeln('排序前的数据:');
对于i:=低(MyArray)到高(MyArray)do
开始
写入(MyArray[i]+'';
结束;
书面语;
合并排序(MyArray);
writeln('排序前的数据:');
对于i:=低(MyArray)到高(MyArray)do
开始
写入(MyArray[i]+'';
结束;
readln;
结束。

在mereSort函数中,我回忆起数组“left”和“right”上的merge sort函数,我得到了错误消息,但我不太明白为什么会这样?

这有许多不同的错误,希望这些点能帮助您朝着正确的方向前进

数组索引的问题 您的索引超出了数组的末尾: 动态数组从零开始索引,因此

    for i := 0 to Length(left) do
应该是

    for i := 0 to Length(left) - 1 do
或者你可以使用

   for i := Low(left) to High(left) do
就像你后来做的那样

我建议您选择一个标准表单并一致地使用它,并且避免使用基于非零的索引声明常量数组,除非您有充分的理由,这样您就可以一致地使用相同的表单,或者以后更改数组的类型而不会遇到麻烦

第一个修复程序将停止程序崩溃,但您会注意到排序代码没有改变任何东西

参数传递问题 Delphi有几种不同的方法将参数传递到过程中:

procedure doSomething(a : array of string);
procedure doSomething(var a : array of string);
procedure doSomething(out a : array of string);
procedure doSomething(const a : array of string);
这些参数确定了过程内部发生的事情如何影响传递的原始变量

这是您需要理解的,请阅读文档:

在我看来,与数组参数相关的一些行为和语法非常混乱,而且许多看起来直观的东西是不允许的,尤其是对于XE/旧版本,阅读有关标准数据类型的文档是值得的

在当前状态下,合并过程将不起作用,因为它只对传入的数组的新副本进行操作,该副本也声明为常量

其他 我会避免使用
result
作为过程参数,因为这是函数返回值使用的名称,这样使用它似乎是自找麻烦


PS:我没有看合并的逻辑,只是基本的语言错误

当你在调试器中单步执行代码时,你看到了什么?@KenWhite我完全忘记了单步执行我的程序。。。我很抱歉。我意识到我不认为它在一开始就正确地设置了左右数组,因为我一步一步地看清楚了变量包含了什么。请记住,对于小集合来说,合并排序效率非常低,这就是为什么在元素数量较少时,最高效的合并排序实现使用插入排序。因此,您开始递归地使用合并排序,但当左/右数组变小时,您将切换到插入排序以完成此过程。根据我的经验,这个“神奇”数字介于8到32个元素之间,但可能会有所不同。你忘记调试你的程序了吗?来吧。@DavidHeffernan Yeh我知道的没错..:(我是自学成才的,对这一点还不熟悉:DWow非常感谢您的详细分析。我一定会通读这篇文章,然后回复您,但现在我在哪里已经很晚了,但我真的很感谢您的时间和帮助。这种行为并不是很令人困惑。您应该知道,您所有的示例都是开放的。)s而不是动态数组。有关这些数组的详细信息:。
procedure doSomething(a : array of string);
procedure doSomething(var a : array of string);
procedure doSomething(out a : array of string);
procedure doSomething(const a : array of string);