我遇到了以下(概念上非常简单)的问题,并希望编写代码来实现它,但我正在努力。假设我们有两行相等的长度,k。每行的每个单元格可以是0或1.
例如,考虑以下行对,k = 5:01011,00110
现在,如果两行可以在每个单元格中自由交换值,则可能存在2 ^ 5种可能的行对组合(其中一些可能不是唯一的)。例如,我们可以将00010,01111作为上述数据中的一个可能的行对。我想在Delphi中编写代码来列出所有可能的行对。这对于一组嵌套的for循环来说很容易。但是,如果只在运行时知道k的值,我不知道如何使用这种方法,我不知道我需要多少索引变量。我无法看到案例陈述如何帮助,因为我不知道k的价值。
我希望有一个嵌套for循环的替代方案,但任何想法都会受到赞赏。感谢。
答案 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.