如何跳过 delphi 中的一些嵌套循环?
How to skip some nested loops in delphi?
有人可以在 Delphi 中帮助我解决这个问题吗?
我有 5 个嵌套的 "for" 块循环迭代变量 k1, k2.. k5.
另一个变量 k 必须控制以上 5 个循环的深度。此变量是在 运行 时间内定义的。
是否可以消除k个内部'for'块的执行,就好像它们被注释了一样?这里有一个简短的解释代码清单:
k := 2;
for k1 := 1 to 100 do begin
for k2 := 1 to 100 do begin
for k3 := 1 to 100 do begin
for k4 := 1 to 100 do begin {want to skip this loop}
for k5 := 1 to 100 do begin {want to skip this loop}
AnywayDoThat; // must execute anyway
end; {k5}
end; {k4}
end;
end;
end;
进一步说明,由于k等于2,我希望避免执行循环k4和k5(以大括号结尾的代码行),从而缩短程序的完整流程。当然,proc AnywayDoThat 必须执行。
我用Delphi6.
编辑: 抱歉措辞不当 'eliminated'。目的是避免不必要的迭代。通过使其只执行一次来跳过循环的技巧是完美的。因此,proc AnywayDoThat 仅根据 k1、k2、k3 达到。
您可以使用以下技巧
Var
Maxes: array [1..5] of integer;
Eliminators: array [1..5] of integer; // they have to be of same length
begin
SetArray(Maxes, [100, 100, 100, 100, 100]);
SetArray(Eliminators, [1, 1, 1, 1, 1]);
// Here you set K
K := 2; // you need to make sure K <= 5
// Set the Eliminators array
for I := 1 to K do
begin
Eliminators[5-I+1] := Maxes[5-I+1];
end;
// Now to the loops
for k1 := 1 to Maxes[1] div Eliminators[1] do begin
for k2 := 1 to Maxes[2] div Eliminators[2] do begin
for k3 := 1 to Maxes[3] div Eliminators[3] do begin
for k4 := 1 to Maxes[4] div Eliminators[4] do begin
for k5 := 1 to Maxes[5] div Eliminators[5] do begin
AnywayDoThat; // must execute anyway
end;
end;
end;
end;
end;
end;
这里的主要思想是通过让它执行一次来跳过循环。这可以进一步修改以使其跳过任何循环。
另一种方法是使用递归。这是一个相当简单的示例,它基于将当前索引写入文本文件的代码(抱歉,没有 Delphi 6 用于测试):
var
F: Textfile;
procedure AnywayDoThat(const Index: array of Integer);
var
I: Integer;
begin
for I := Low(Index) to High(Index) do
Write(F, Index[I], '.');
Writeln(F);
end;
procedure Loop(Level, MaxLevel: Integer; const Index: array of Integer);
var
arr: array of Integer;
I: Integer;
L: Integer;
begin
if Level < MaxLevel then begin
L := Length(Index);
SetLength(arr, L + 1);
for I := 0 to L - 1 do begin
arr[I] := Index[I];
end;
for I := 1 to 100 do begin
arr[L] := I;
Loop(Level + 1, MaxLevel, arr);
end;
end
else begin
AnywayDoThat(Index);
end;
end;
procedure Main();
var
k: Integer;
I: Integer;
Index: array of Integer;
begin
AssignFile(F, 'c:\Temp\test.txt');
Rewrite(F);
k := 2;
SetLength(Index, 1);
for I := 1 to 100 do begin
Index[0] := I;
Loop(1, 5 - k, Index);
end;
Close(F);
end;
有人可以在 Delphi 中帮助我解决这个问题吗?
我有 5 个嵌套的 "for" 块循环迭代变量 k1, k2.. k5.
另一个变量 k 必须控制以上 5 个循环的深度。此变量是在 运行 时间内定义的。
是否可以消除k个内部'for'块的执行,就好像它们被注释了一样?这里有一个简短的解释代码清单:
k := 2;
for k1 := 1 to 100 do begin
for k2 := 1 to 100 do begin
for k3 := 1 to 100 do begin
for k4 := 1 to 100 do begin {want to skip this loop}
for k5 := 1 to 100 do begin {want to skip this loop}
AnywayDoThat; // must execute anyway
end; {k5}
end; {k4}
end;
end;
end;
进一步说明,由于k等于2,我希望避免执行循环k4和k5(以大括号结尾的代码行),从而缩短程序的完整流程。当然,proc AnywayDoThat 必须执行。
我用Delphi6.
编辑: 抱歉措辞不当 'eliminated'。目的是避免不必要的迭代。通过使其只执行一次来跳过循环的技巧是完美的。因此,proc AnywayDoThat 仅根据 k1、k2、k3 达到。
您可以使用以下技巧
Var
Maxes: array [1..5] of integer;
Eliminators: array [1..5] of integer; // they have to be of same length
begin
SetArray(Maxes, [100, 100, 100, 100, 100]);
SetArray(Eliminators, [1, 1, 1, 1, 1]);
// Here you set K
K := 2; // you need to make sure K <= 5
// Set the Eliminators array
for I := 1 to K do
begin
Eliminators[5-I+1] := Maxes[5-I+1];
end;
// Now to the loops
for k1 := 1 to Maxes[1] div Eliminators[1] do begin
for k2 := 1 to Maxes[2] div Eliminators[2] do begin
for k3 := 1 to Maxes[3] div Eliminators[3] do begin
for k4 := 1 to Maxes[4] div Eliminators[4] do begin
for k5 := 1 to Maxes[5] div Eliminators[5] do begin
AnywayDoThat; // must execute anyway
end;
end;
end;
end;
end;
end;
这里的主要思想是通过让它执行一次来跳过循环。这可以进一步修改以使其跳过任何循环。
另一种方法是使用递归。这是一个相当简单的示例,它基于将当前索引写入文本文件的代码(抱歉,没有 Delphi 6 用于测试):
var
F: Textfile;
procedure AnywayDoThat(const Index: array of Integer);
var
I: Integer;
begin
for I := Low(Index) to High(Index) do
Write(F, Index[I], '.');
Writeln(F);
end;
procedure Loop(Level, MaxLevel: Integer; const Index: array of Integer);
var
arr: array of Integer;
I: Integer;
L: Integer;
begin
if Level < MaxLevel then begin
L := Length(Index);
SetLength(arr, L + 1);
for I := 0 to L - 1 do begin
arr[I] := Index[I];
end;
for I := 1 to 100 do begin
arr[L] := I;
Loop(Level + 1, MaxLevel, arr);
end;
end
else begin
AnywayDoThat(Index);
end;
end;
procedure Main();
var
k: Integer;
I: Integer;
Index: array of Integer;
begin
AssignFile(F, 'c:\Temp\test.txt');
Rewrite(F);
k := 2;
SetLength(Index, 1);
for I := 1 to 100 do begin
Index[0] := I;
Loop(1, 5 - k, Index);
end;
Close(F);
end;