![]() |
Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Hallo,
3 Variablen
Delphi-Quellcode:
bOK soll jetzt nur True sein, wenn nur einer der 3 Werte True ist.
var
B1, B2, B3: Boolean; bOK: Boolean; begin // bOK := ?? end; Mein bisheriger Ansatz:
Delphi-Quellcode:
usw.
bOK := False;
if B1 then begin bOK := True; end; if B2 then begin if bOK then begin bOK := False; Exit; end; bOK := B2; end; if Be then begin Irgendwie ist heute Montag ... Wie löst man das eleganter ??? Ich will nicht viele And's und Or's haben.
Delphi-Quellcode:
Naja, jetzt habe ich halt doch and's und or's ...
if ((B1=True) and (B2=False) and (B3=False)) or
((B1=False) and (B2=True) and (B3=False)) or ((B1=False) and (B2=False) and (B3=True)) then begin bOK := True; end; Heiko |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Mit einer OR Verknüpfung?
Delphi-Quellcode:
bOK := B1 or B2 or B3;
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Delphi-Quellcode:
bOK := B1 xor B2 xor B3;
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Warum XOR?
Ah ja. Stimmt. Hast Recht. Bei mir wäre bOK auch wahr, wenn zwei oder drei wahr wären, es darf aber nur einer wahr sein. |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Delphi-Quellcode:
Gruß
w:=0;
if B1 then inc(w,1); if B2 then inc(w,1); if B3 then inc(w,1); bok:=W=1; K-H |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Hallo,
ja, mit dem Inc und Hochzählen sieht elegant aus ;) Da kommt man nach 17:00 nicht drauf ... ;) Ah so: elegant und trotzdem leserlich sollte es sein. Jetzt schmeisse ich mal den Profiler an und mal schaun, was am schnellsten bei 1.000.000 Vergleiche ist. Danke Heiko |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Zitat:
Delphi-Quellcode:
bOK := IfThen(B1, 1, 0) + IfThen(B2, 1, 0) + IfThen(B3, 1, 0) = 1;
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
(Das XOR "gefällt" mir besser. -- Shit nicht zu ende gedacht) (kommt wohl darauf an mit welchen Hilfskonstruktionen man zuerst gearbeitet hat) Laß mal hören was effektiver ist. Gruß K-H |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Für den Datentype Boolean (WordBool ausgenommen) funktioniert folgendes:
Delphi-Quellcode:
Ich ergänze:
bOk := Ord(b1) +Ord(b2) +Ord(b3) = 1
Wenn man so etwas wie
Delphi-Quellcode:
macht wird es auch hässlich. :-)
b1 := Boolean(11);
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Delphi-Quellcode:
:stupid:
bOk := Ord( b1 ) + Ord( b2 ) + Ord( b3 ) = Ord( true );
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Zitat:
Delphi-Quellcode:
drüber ;-)
{Assembler-Code macht folgendes:
w:=0; if B1 then inc(w,1); if B2 then inc(w,1); if B3 then inc(w,1); bok:=W=1;} |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Delphi-Quellcode:
bOK := (B1 xor B2 xor B3) and not (B1 and B2 and B3);
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Meine Anerkennung! |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Eventuell so?
Delphi-Quellcode:
function IsOneOfThree( const B1, B2, B3: Boolean ): Boolean;
begin Result := ( B1 xor B2 xor B3 ) and not ( B1 and B2 and B3 ); end; function IsOneOfFour( const B1, B2, B3, B4: Boolean ): Boolean; begin Result := IsOneOfThree( IsOneOfThree( B1, B2, B3 ), B4, False ); end; |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Für die beliebige Anzahl an Bool-Werten (Array) würde mir jetzt eher so etwas vorschweben:
Delphi-Quellcode:
function IsOnlyOneTrue(const BoolArr: TArray<Boolean>): Boolean;
var I: Integer; begin Result := False; for I := Low(BoolArr) to High(BoolArr) do if BoolArr[I] then if Result then Exit(False) else Result := True; end; |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Hallo,
nachdem ich den Code gezeigt habe, wurde mir gesagt "Falsch!", der erste True-Wert wird genommen, egal wie viele True sind ;) Heiko |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
bOK := (B1 xor B2 xor B3 xor B4) and not (B1 and B2 and B3 and B4) vermutlich aber falsch, wie mir jetzt dämmert, weil das Zwischenergebnis der xor-Operationen ständig alterniert (ich bin jetzt auf die Schnelle zu bequem zum Denken oder Probieren). Es kommt also darauf an, daß die Anzahl der Operanden (un)gerade bleibt. Bei 5 Operanden bOK := (B1 xor B2 xor B3 xor B4 xor B5) and not (B1 and B2 and B3 and B4 and B5) sollte es aber wieder stimmen. Edit: Asche auf mein Haupt, es klappt weder mit 4en noch mit 5en. Ist wohl doch nicht verallgemeinerbar. Schade. |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Ich würde auch ein Bool Array vorziehen:
Delphi-Quellcode:
function IsNumberOfValuesSet(const AValues : array of Boolean; AMax : Integer = 1) : Boolean;
var LCount : Integer; begin LCount := 0; for Result in AValues do if Result then begin Inc(LCount); if LCount > AMax then Break; end; Result := LCount = AMax; end; begin Writeln(IsNumberOfValuesSet([False])); Writeln(IsNumberOfValuesSet([False, True])); Writeln(IsNumberOfValuesSet([False, True, False])); Writeln(IsNumberOfValuesSet([False, True, False, True])); Writeln(IsNumberOfValuesSet([False, True, False, True], 2)); Readln; end. |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Delphi-Quellcode:
Wobei man das ja eigentlich nicht macht.
B1=True
Die mathematischen Lösungen mit Ord gehen natürlich nur unter der Annahme, daß man davon ausgeht, daß nur True oder False drin steht. Wobei True = not False, bzw. True <> "True". Der Delphi-Boolean kennt ja 254 "True" und ein False, deswegen auch niemals
Delphi-Quellcode:
:stupid:
B1=True
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
oder sowas
function CountTrues (ABoolean :array of Boolean):Integer for i ... result := result + ((-1)*strtoint(booltostr(ABoolean [i]))) |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Und das "=true" passiert vermutlich auch so manchem gestandenen Programmierer dann und wann, das ist einfach mental zu aufdringlich. Dito: "=false" anstatt "if not".... |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Nein, das darf nicht abgefangen werden.
Es kommt auf die "Auswertung an, also ob man es logisch oder binär vergleich ... = ist in Pascal immer "binär". Nur bei der Typkonvertierung zwischen Boolean/ByteBool/WordBool/LongBool/Variant wird der logische Wert konvertiert. |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Um das nochmal aufzugreifen:
(~a*~b*c)+(~a*b*~c)+(a*~b*~c) in ![]() Kannst auch die KNF nehmen ((a+b+c) * (~b+~c) * (~a+~c) * (~a+~b)), aber das bringt dich ja auch nicht wirklich weiter. Also: B1 := (not B1 and not B2 and B3) or (not B1 and B2 and not B3) or (B1 and not B2 and not B3); |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Delphi-Quellcode:
(maximal 1) und
if Ord(A) + Ord(B) + Ord(C) <= 1 then
Delphi-Quellcode:
(immer 1)
if Ord(A) + Ord(B) + Ord(C) = 1 then
geht halt nur, wenn wirklich nur True und False drin stehen. Einen Cast von Boolean auf Byte und zurück macht Delphi immer nur binär. Es gibt in Pascal keine Möglichkeit zu steuern ob Binär oder Logisch konvertiert wird. (es gibt immer nur je Eines von Beidem)
Delphi-Quellcode:
if Ord(A <> False) + Ord(B <> False) + Ord(C <> False) = {<=} 1 then
Delphi-Quellcode:
arbeitet bei einem Boolean logisch und nicht binär (glaub ich), also ginge auch
NOT
Delphi-Quellcode:
if Ord(not A) + Ord(not B) + Ord(not C) = {>=} 2 {3-1} then
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Wie wäre es, wenn man sich dafür eine Hilfsfunktion baut?
Pseudocode:
Code:
Fände ich am elegantesten, solange sich ein Array noch nicht lohnt.
def OneIfTrue(mybool):
return 1 if mybool else 0 def ExactlyOneIsTrue(b1, b2, b3): return OneIfTrue(b1) + OneIfTrue(b2) + OneIfTrue(b2) == 1 |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Delphi-Quellcode:
, bzw.
OneIfTrue
Delphi-Quellcode:
sollten aber hoffentlich als Inline-Funktion vorliegen.
IfThen(b1, 1, 0)
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Wie wäre denn:
Delphi-Quellcode:
b4 := Ord(b1 and True) + Ord(b2 and True) + Ord(b3 and True) = 1;
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Delphi-Quellcode:
und
x and True
Delphi-Quellcode:
arbeiten logisch, also ja ...... faaaaaaaaalls der Compiler das nicht "optimiert" und weg lässt. :zwinker:
x or False
|
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Ja, ist getestet und hat bei mir funktioniert.
Habe bewusst mit Werten ungleich 1 für die Variablen getestet. |
AW: Elegante Lösung gesucht, 3 Boolean-Werte, nur einer darf gesetzt sein
Zitat:
Delphi-Quellcode:
oder
function CountChecked(AValues: Array of Boolean): Integer;
var i: Integer; begin Result := 0; for I := Low(AValues) to High(AValues) do if AValues[i] then inc(Result); end;
Delphi-Quellcode:
function CountChecked(AValues: Array of Boolean): Integer;
var i: Integer; begin Result := 0; for I := Low(AValues) to High(AValues) do Inc(Result, Ord(AValues[i] <> false)); end; Aufruf:
Delphi-Quellcode:
So kann man beliebig viele Parameter übergeben und hat die Möglichkeit zu entscheiden
if CountChecked([True, False, Boolean(3), Boolean(0), Boolean(99), Boolean(-1)]) = 1 then
... wie viele true sein müssen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz