Lazarus 中两个数组的比较

Comparison of two arrays in Lazarus

我对 Pascal 有疑问,尤其是 Lazarus。

首先,我创建了两个随机整数数组:

    procedure TForm1.b_arraycreate1Click(Sender: TObject);
begin
   randomize;
   for i := 1 to 5 do
      arr1[i] := random(10);
end;

procedure TForm1.b_arraycreate2Click(Sender: TObject);
begin
   randomize;
   for j := 1 to 5 do
       arr2[j] := random(10);
end; 

我知道,我也可以把它放在一个过程中,但现在没关系了。

我想比较一下这两个。我写了下面的代码:

procedure TForm1.b_comparisonClick(Sender: TObject);
var v:boolean;
begin

for i := 1 to 5 do begin
       for j := 1 to 5 do begin
           if   arr1[i] = arr2[j]
                then
                    begin
                         v:=true;
                    end
                else
                    begin
                         v:=false;
                    end;
       end;
end;

if v = true
     then
         begin
              ShowMessage('Yes, there is a similarity! You can find number ' +IntToStr(arr1[i])+ ' in array 1, position ' +IntToStr(i)+ ' and also in array 2, position ' +IntToStr(j)+ '.');
         end
     else
     begin
          ShowMessage('No similarities... Generate new ones!');
    end
end;  

用我自己的话说:我想按下一个按钮,然后应该有一条消息 window,其中包含如果数组 1 中存在一个数字(例如 7)的信息 and array 2.如果有,还要写这个数的位置(index)。

不幸的是,这个程序不起作用,我不知道为什么。它总是显示"No similarities"(不用担心数组的创建。我还有一个标签,每次都可以测试数组的内容)。

我的代码中是否存在(愚蠢的)错误?

正如 MartynA 在他的评论中所解释的那样,您的算法是错误的。你的话是:

if there is one number which exists in array 1 and array 2

要查看是否如此,您必须扫描所有 array1,并且对于每个数字,查看它是否存在于 array2 中的某处。

所以是的,您需要两个循环,一个嵌套在另一个循环中。一旦找到信件,就必须停下来。或者,如果您想要更多结果(找到多个重复项),请显示一条消息而不是停止 - 然后继续。第三种可能性(更复杂):找到后,存储两个索引(不覆盖旧结果......)并继续。我只会显示第一个选项:

procedure TForm1.b_comparisonClick(Sender: TObject);
var
  i,j: integer;
  v:   boolean;

begin
  v := false;
  for i := 1 to 5 do begin
    for j := 1 to 5 do begin
      if arr1[i] = arr2[j] then begin
        v := true;
        break
      end
    end  // inner, j
  end;  // outer, i

  if v = true
    then ShowMessage(.....)
    else ShowMessage('No similarities...');
end;  // proc comparison

我试着尊重你的代码,有一些可能"shortcuts";例如,如果 v 是一个布尔变量,最好写成 if v then 而不是 if v=true then,还有一些其他的,比如

v := arr1[i]=arr[j];

...或者...外循环不需要begin+end.

******* 注意(请参阅下面关于 break 的评论) 从两个嵌套循环到 stop/exit 并不是那么简单...也许 goto...上面的代码有效,但 break 几乎没有作用。

******* 第二次更新,如下评论所述。它不起作用,因为如果中断不退出两个循环,则外部索引将被修改。使用两次休息的正确循环如下:

  for i := 1 to 5 do begin
    for j := 1 to 5 do begin
      if arr1[i] = arr2[j] then begin
        v := true;
        break
      end
    end;  // inner, j
    if v then break
  end;  // outer, i

对错误表示抱歉...:-)

我更喜欢使用 GOTO 来退出两个循环:它速度更快、指令单一且更清晰("goto found" 而不是通用中断)。但是GOTO不是很流行...所以我一直很害怕!