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

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:没看合并的逻辑,只是基本的语言错误