独占评估多个布尔条件,只有一个可以为真(Delphi)

Evaluate multiple boolean conditions exclusively, only one can be true (Delphi)

我有一个函数,它评估多个(在我的例子中是 7 个)布尔变量和条件,如果只有其中一个为真(当然其余为假),则结果为真。我有以下代码:

function GetExclusiveTrue: boolean;
begin
  Result:= (
    Integer(BoolVar1) + 
    Integer(BoolVar2) + 
    Integer(BoolFunc3) + 
    Integer(BoolVar4) + 
    Integer(BoolFunc5) + 
    Integer(BoolVar6) + 
    Integer(BoolVar7)) = 1;
end;

我只是想知道是否有比这更好的解决方案?

PS:我想我没有正确定义我的问题是什么。

我正在寻找仅使用逻辑运算符的解决方案,不涉及任何转换。

PS2:看来我无法正确解释我在寻找什么。我想看到一个没有迭代、选择、函数调用等的解决方案。只允许布尔运算符。为什么?我只想知道这是否可能。寻找提供与上述函数相同结果的逻辑运算组合。

一个更好的解决方案可能是,你做一个开放数组作为

function GetExclusiveTrue(Values: array of Boolean ): Boolean;

并通过迭代求和。

如果你不想投射,那么你可以通过这种方式实现同​​样的目的:

function GetExclusiveTrue: boolean;
var
  Count: Integer;
begin
  Count := 0;
  if BoolVar1 then
    Inc(Count);
  if BoolVar2 then
    Inc(Count);
  if BoolFunc3 then
    Inc(Count);
  if BoolVar4 then
    Inc(Count);
  if BoolFunc5 then
    Inc(Count);
  if BoolVar6 then
    Inc(Count);
  if BoolVar7 then
    Inc(Count);
  Result := (Count = 1);
end;

这是一个只计算 1-true 的函数,无论要检查的布尔值有多少:

function GetExclusiveTrue(boolarray: array of Boolean) : Boolean;
var
  arrayindex  : integer;
begin
  result := false;
  for arrayindex := 0 to high(boolarray) do
    if boolarray[arrayindex] then
    begin
      result := not result;
     if not result then exit;
    end;
end;

首先,假设一个 false 结果,然后扫描提供的数组。在找到的第一个 true(如果有)上将 return 值设置为真,如果找到第二个 true.

,则清除 return 值并退出

这是计算有多少为真的特例:

function howmanytrue(boolarray: array of Boolean) : integer;
var
  arrayindex  : integer;
begin
  result := 0;
  for arrayindex := 0 to high(boolarray) do
    if boolarray[arrayindex] then inc(result);
end;

显然,GetExclusiveTrue = howmanyaretrue([your Booleans]) = 1 但这允许其他问题,例如 are none/all/all-but-1/majority/at-least-3/no-more-than-2/exactly-half true(假设您知道您正在检查的布尔数.)

我用一组 11 个复选框和 2 个面板对此进行了测试

procedure TForm1.CheckBoxClick(Sender: TObject);
begin
  Panel1.Caption := BoolToStr(GetExclusiveTrue([checkbox1.Checked,checkbox2.Checked,checkbox3.Checked,checkbox4.Checked,checkbox5.Checked,checkbox6.Checked,checkbox7.Checked,checkbox8.Checked,checkbox9.Checked,checkbox10.Checked,checkbox11.Checked]),true);
  Panel2.Caption := IntToStr(howmanytrue([checkbox1.Checked,checkbox2.Checked,checkbox3.Checked,checkbox4.Checked,checkbox5.Checked,checkbox6.Checked,checkbox7.Checked,checkbox8.Checked,checkbox9.Checked,checkbox10.Checked,checkbox11.Checked]));
end;

I want to see a solution without iteration, selection, function calls, etc. ONLY boolean operators allowed. Why? I just want to know if that is possible or not. Looking for a combination of logical operations which provides the same result as the function above.

您只想使用逻辑运算符 andorxornot 来实现它。事情是这样的:

Result :=
     (b1 and not (b2 or b3 or b4))
  or (b2 and not (b1 or b3 or b4))
  or (b3 and not (b1 or b2 or b4))
  or (b4 and not (b1 or b2 or b3));

我举了一个只有四个布尔值的例子,但这个概念对于任何数字都是一样的。