替代Delphi中的嵌套for循环

时间:2013-09-06 17:44:32

标签: delphi

我遇到了以下(概念上非常简单)的问题,并希望编写代码来实现它,但我正在努力。假设我们有两行相等的长度,k。每行的每个单元格可以是0或1.

例如,考虑以下行对,k = 5:01011,00110

现在,如果两行可以在每个单元格中自由交换值,则可能存在2 ^ 5种可能的行对组合(其中一些可能不是唯一的)。例如,我们可以将00010,01111作为上述数据中的一个可能的行对。我想在Delphi中编写代码来列出所有可能的行对。这对于一组嵌套的for循环来说很容易。但是,如果只在运行时知道k的值,我不知道如何使用这种方法,我不知道我需要多少索引变量。我无法看到案例陈述如何帮助,因为我不知道k的价值。

我希望有一个嵌套for循环的替代方案,但任何想法都会受到赞赏。感谢。

2 个答案:

答案 0 :(得分:4)

给定长度为 k 的两个向量 A B ,我们可以生成一对新的向量 A1 通过有选择地从 A B 中选择元素来选择 B1 。让我们选择 A B 的决定由位向量 S 决定,长度为 k 。对于<0> k 中的 i ,当 S i 为0时,存储 A < A1 i 中的sub> i B1中的 B i <子> I 的。如果 S i 为1,则反之亦然。

我们可以在Delphi中用这样的函数定义:

procedure GeneratePair(const A, B: string; S: Cardinal; out A1, B1: string);
var
  k: Cardinal;
  i: Cardinal;
begin
  Assert(Length(A) = Length(B));
  k := Length(A);
  Assert(k <= 32);

  SetLength(A1, k);
  SetLength(B1, k);
  for i := 1 to k do
    if (S and (1 shl Pred(i))) = 0 then begin
      A1[i] := A[i];
      B1[i] := B[i];
    end else begin
      A1[i] := B[i];
      B1[i] := A[i];
    end;
end;

如果我们计算从0到2 k -1的二进制数,那将给出一系列位向量,表示交换或不交换的所有可能组合 A B 之间的字符。

我们可以写一个循环并使用上面的函数来生成所有2个 k 组合:

A := '01011';
B := '00110';
for S := 0 to Pred(Round(IntPower(2, Length(A)))) do begin
  GeneratePair(A, B, S, A1, B1);
  writeln(A1, ', ', B1);
end;

有效地使用一组嵌套循环。外循环是从0到31的循环。内循环是函数内部从1到k的循环。如您所见,我们不需要事先知道 k 的值。

答案 1 :(得分:1)

现在,感谢Rob,我理解了这个问题,我提供了这种递归解决方案:

{$APPTYPE CONSOLE}

procedure Swap(var A, B: Char);
var
  temp: Char;
begin
  temp := A;
  A := B;
  B := temp;
end;

procedure Generate(const A, B: string; Index: Integer);
var
  A1, B1: string;
begin
  Assert(Length(A)=Length(B));
  inc(Index);
  if Index>Length(A) then // termination
    Writeln(A, ', ', B)
  else
  begin // recurse
    // no swap
    Generate(A, B, Index);

    //swap
    A1 := A;
    B1 := B;
    Swap(A1[Index], B1[Index]);
    Generate(A1, B1, Index);
  end;
end;

begin
  Generate('01011', '00110', 0);
  Readln;
end.