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不是很流行...所以我一直很害怕!
我对 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不是很流行...所以我一直很害怕!