无效的指针操作;递归合并排序
Invalid pointer operation; Recursive Merge Sort
我试图对字符串进行合并排序,但是我无法执行递归部分,并且出现错误 "Invalid Pointer Operation"
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var i : Integer;
const MyArray : array[1..5]of string = ('hi', 'zebra', 'apple', 'Xylophone', 'dog');
Procedure merge(result, left, right : array of string);
var i, i1, i2 : Integer;
begin
i1 := 0;
i2 := 0;
for i := 0 to Length(result) do
begin
if (i2 >= Length(right)) or (i1 < Length(left)) and (StrComp(PChar(left[i]), PChar(right[i2])) < 0) then
begin
result[i] := left[i1];
inc(i1);
end
else
begin
result[i] := right[i2];
inc(i2);
end;
end;
end;
Procedure mergeSort(OriginalList : array of string);
var left, right : array of string;
i : Integer;
begin
if (Length(OriginalList) >= 2) then
begin
setlength(left, length(OriginalList) div 2);
setlength(right, length(OriginalList) - (length(OriginalList) div 2));
for i := 0 to Length(left) do
begin
left[i] := OriginalList[i];
end;
for i := 0 to Length(right) do
begin
right[i] := OriginalList[i + Length(OriginalList) div 2];
end;
mergeSort(left);
mergeSort(right);
merge(OriginalList, left, right);
end;
end;
begin
writeln('The data before sorting: ');
for i := low(MyArray) to High(MyArray) do
begin
write(MyArray[i]+' ');
end;
writeln;
mergeSort(MyArray);
writeln('The data before sorting: ');
for i := low(MyArray) to High(MyArray) do
begin
write(MyArray[i]+' ');
end;
readln;
end.
在 mereSort 函数的那一行,我想起了数组 "left" 和 "right" 的合并排序函数,我收到了错误消息,但我不太明白为什么?
这里有很多不同的地方,希望这些要点能帮助你朝着正确的方向前进。
数组索引问题
您的索引超出了数组的末尾:
动态数组是从零开始索引的,所以行
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);
这些决定了过程内部发生的事情如何影响传递的原始变量
这是您需要了解的内容,请阅读文档:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Parameters_(Delphi)
IMO 有一些与数组参数相关的非常令人困惑的行为和语法,而且很多看起来很直观的东西是不允许的,尤其是 XE/older 版本,值得阅读有关标准数据类型的文档
在当前状态下,您的合并过程将不起作用,因为它只对您传入的数组的新副本进行操作,您也已将其声明为常量
其他
我会避免使用 result
作为过程参数,因为这是用于函数 return 值的名称,这样使用它似乎是自找麻烦。
PS:没看合并的逻辑,只是基本的语言错误
我试图对字符串进行合并排序,但是我无法执行递归部分,并且出现错误 "Invalid Pointer Operation"
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var i : Integer;
const MyArray : array[1..5]of string = ('hi', 'zebra', 'apple', 'Xylophone', 'dog');
Procedure merge(result, left, right : array of string);
var i, i1, i2 : Integer;
begin
i1 := 0;
i2 := 0;
for i := 0 to Length(result) do
begin
if (i2 >= Length(right)) or (i1 < Length(left)) and (StrComp(PChar(left[i]), PChar(right[i2])) < 0) then
begin
result[i] := left[i1];
inc(i1);
end
else
begin
result[i] := right[i2];
inc(i2);
end;
end;
end;
Procedure mergeSort(OriginalList : array of string);
var left, right : array of string;
i : Integer;
begin
if (Length(OriginalList) >= 2) then
begin
setlength(left, length(OriginalList) div 2);
setlength(right, length(OriginalList) - (length(OriginalList) div 2));
for i := 0 to Length(left) do
begin
left[i] := OriginalList[i];
end;
for i := 0 to Length(right) do
begin
right[i] := OriginalList[i + Length(OriginalList) div 2];
end;
mergeSort(left);
mergeSort(right);
merge(OriginalList, left, right);
end;
end;
begin
writeln('The data before sorting: ');
for i := low(MyArray) to High(MyArray) do
begin
write(MyArray[i]+' ');
end;
writeln;
mergeSort(MyArray);
writeln('The data before sorting: ');
for i := low(MyArray) to High(MyArray) do
begin
write(MyArray[i]+' ');
end;
readln;
end.
在 mereSort 函数的那一行,我想起了数组 "left" 和 "right" 的合并排序函数,我收到了错误消息,但我不太明白为什么?
这里有很多不同的地方,希望这些要点能帮助你朝着正确的方向前进。
数组索引问题
您的索引超出了数组的末尾: 动态数组是从零开始索引的,所以行
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);
这些决定了过程内部发生的事情如何影响传递的原始变量
这是您需要了解的内容,请阅读文档: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Parameters_(Delphi)
IMO 有一些与数组参数相关的非常令人困惑的行为和语法,而且很多看起来很直观的东西是不允许的,尤其是 XE/older 版本,值得阅读有关标准数据类型的文档
在当前状态下,您的合并过程将不起作用,因为它只对您传入的数组的新副本进行操作,您也已将其声明为常量
其他
我会避免使用 result
作为过程参数,因为这是用于函数 return 值的名称,这样使用它似乎是自找麻烦。
PS:没看合并的逻辑,只是基本的语言错误