Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - komplizierte Verschachtelungen mit "if then" / "case of"
Dibelius - Di 29.04.08 17:05
Titel: komplizierte Verschachtelungen mit "if then" / "case of"
Hi,
ich möchte bei meinem Programm (zur Differentialrechnung) ein paar Optimierungen vornehmen. Vorweg: ich hab mich dabei auf nur 3 Funktionstypen festgelegt, lineare, quadratische Fkt. sowie solche 3. Grades.
Mein erstes Problem ist nun die Ausgabe der Funktionsgleichung. Es funktioniert zwar, aber die function, die ich dafür schreiben musste, ist ein einziger Wulst aus case of (für Funktionstyp) und if then Verschachtelungen (für Parameter a - d). Hier die function, wie ich sie momentan habe - wohlgemerkt fehlt noch die Fkt. 3. Grades...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| function ErstelleFunktionsgleichung: string; begin case FuncType of 1:begin if (a=0) then begin if (b=0) then result:= sfx+' = 0'; if (b<>0) then result:= Format(sfx+' = %s', [b]); end else begin if (b=0) then result:= Format(sfx+' = %sx', [a]); if (b<0) then result:= Format(sfx+' = %sx %s', [a,b]); if (b>0) then result:= Format(sfx+' = %sx +%s', [a,b]); end; end; 2:begin if (a=0) then begin if (b=0) then begin if (c=0) then result:= sfx+' = 0'; if (c<>0) then result:= Format(sfx+' = %s', [c]); end else begin if (c=0) then result:= Format(sfx+' = %sx', [b]); if (c<0) then result:= Format(sfx+' = %sx %s', [b,c]); if (c>0) then result:= Format(sfx+' = %sx +%s', [b,c]); end; end else begin if (b=0) then begin if (c=0) then result:= Format(sfx+' = %sx²', [a]); if (c<0) then result:= Format(sfx+' = %sx² %s', [a,c]); if (c>0) then result:= Format(sfx+' = %sx² +%s', [a,c]); end else begin if (b<0) then begin if (c=0) then result:= Format(sfx+' = %sx² sx', [a,b]); if (c<0) then result:= Format(sfx+' = %sx² %sx %s', [a,b,c]); if (c>0) then result:= Format(sfx+' = %sx² %sx +%s', [a,b,c]); end; if (b>0) then begin if (c=0) then result:= Format(sfx+' = %sx² +sx', [a,b]); if (c<0) then result:= Format(sfx+' = %sx² +%sx %s', [a,b,c]); if (c>0) then result:= Format(sfx+' = %sx² +%sx +%s', [a,b,c]); end; end; end; end; 3:begin end; end; end; |
Es soll vom Prinzip her alles so bleiben.
Parameter des Wertes 0 bleiben unberücksichtigt und erscheinen nicht im string.
Ist ein Parameter positiv, dann bekommt er ein vorangestelltes '+'
Die Ausgabe soll natürlich in der Standardform für zb. quadr. Fkt. sein:
f(x) = ax² + bx + c
Wie gesagt, es funktioniert auch alles, nur frage ich mich, ob es nicht eine elegantere Lösung gibt, mit der man sehr viel weniger Zeilen Code braucht... ich meine, ich will gar nicht dran denken, was wäre, wenn ich noch Funktionen 5. oder 10. Grades hätte Oo
Wäre nett, wenn sich das mal jemand anschauen könnte. Danke
MfG
Dibelius
Jakob_Ullmann - Di 29.04.08 18:07
Also ich würde auf jeden Fall noch ein paar Mal else einbauen. Warum? Weil dann, wenn die Bedingung davor ausgeführt worden ist, die Zeile mit else übersprungen wird und somit das Proggi ein wenig schneller läuft:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| case FuncType of 1:begin if (a=0) then begin if (b=0) then result:= sfx+' = 0'; if (b<>0) then result:= Format(sfx+' = %s', [b]); end else begin if (b=0) then result:= Format(sfx+' = %sx', [a]); if (b<0) then result:= Format(sfx+' = %sx %s', [a,b]); if (b>0) then result:= Format(sfx+' = %sx +%s', [a,b]); end; end; |
==>
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| case FuncType of 1:begin if (a=0) then begin if (b=0) then result:= sfx+' = 0' else if (b<>0) then result:= Format(sfx+' = %s', [b]); end else begin if (b=0) then result:= Format(sfx+' = %sx', [a]) else if (b<0) then result:= Format(sfx+' = %sx %s', [a,b]) else if (b>0) then result:= Format(sfx+' = %sx +%s', [a,b]); end; end; |
Achso, und diesen Teil:
Delphi-Quelltext
1: 2: 3: 4: 5:
| else begin if (b=0) then result:= Format(sfx+' = %sx', [a]) else if (b<0) then result:= Format(sfx+' = %sx %s', [a,b]) else if (b>0) then result:= Format(sfx+' = %sx +%s', [a,b]); end; |
Brauchst du nicht immer zu wiederholen, du kannst es als extra-Fall betrachten, also anstelle von default in C(++).
delfiphan - Di 29.04.08 18:34
Du solltest auf jeden Fall nicht alle Möglichkeiten ausprogrammieren sondern eine allgemeine Lösung schreiben. Könnte vielleicht so aussehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| function PolyToStr(const AParams: array of Integer; AVarName: Char = 'x'): String; function PrepareSummand(var AFirstNonZero: Boolean; ABase: Integer; AExponent: Integer): String; begin Result := ''; if ABase = 0 then exit; if AFirstNonZero then begin if ABase < 0 then Result := Result + '-'; end else if ABase < 0 then Result := Result + ' - ' else Result := Result + ' + '; ABase := abs(ABase); if (ABase <> 1) or (AExponent = 0) then Result := Result + IntToStr(ABase); if AExponent <> 0 then Result := Result + AVarName; if AExponent >= 2 then Result := Result + '^' + IntToStr(AExponent); AFirstNonZero := False; end; var I: Integer; FirstNonZero: Boolean; begin Result := Format('f(%s) = ', [AVarName]); FirstNonZero := True; for I := 0 to Length(AParams) - 1 do Result := Result + PrepareSummand(FirstNonZero, AParams[I], Length(AParams) - I - 1); if FirstNonZero then Result := Result + '0'; end; |
Beispiele:
PolyToStr([0]) // f(x) = 0
PolyToStr([1]) // f(x) = 1
PolyToStr([0,0,1]) // f(x) = 1
PolyToStr([1,2]) // f(x) = x + 2
PolyToStr([1,2,3]) // f(x) = x^2 + 2x + 3
PolyToStr([1,1,1]) // f(x) = x^2 + x + 1
PolyToStr([-1,-1,-1]) // f(x) = -x^2 - x - 1
PolyToStr([-1,0,0]) // f(x) = -x^2
PolyToStr([1,2,3,4,5,6,7]) // f(x) = x^6 + 2x^5 + 3x^4 + 4x^3 + 5x^2 + 6x + 7
//Edit: unnötiges abs() entfernt
Dibelius - Di 29.04.08 18:46
oh, das kommt dem ganzen schon recht nahe.
Die Parameter sind allerdings vom Typ real. das hab ich vergessen zu erwähnen.
jaenicke - Di 29.04.08 18:50
Das macht ja keinen Unterschied, da musst du ja nur Integer durch Real ersetzen, und entsprechend nicht von Integer in String umwandeln sondern von einer Gleitkommazahl (Float) in String.
delfiphan - Di 29.04.08 19:01
Das schaffst du wohl noch selbst ;)
Dibelius - Di 29.04.08 20:26
indeed :oops:
naja, danke jedenfalls. das hat mir sehr geholfen.
// Edit:
weil ich es in der Funktion gerade sehe: wozu ist die Funktion Abs() gut?
Laut F1 gibt die den absoluten Betrag des Arguments zurück. Wie ist das gemeint und was bewirkt das in deiner Funktion? bspw hier:
Delphi-Quelltext
1: 2:
| if abs(AExponent) >= 2 then Result := Result + '^' + IntToStr(AExponent); |
Wenn AbsoluterBetrag(Exponent) >= 2 dann füge '^' + Exponent-String an
Delete - Di 29.04.08 20:48
abs hat doch jedes auto.
nein spaß beiseite genau weiß ich es auch nicht, aber guckdir mal
das beispiel im hilfe-menu an.
Dibelius - Di 29.04.08 21:00
ja also... wie der Name schon sagt. der Betrag
(ich glaub, ich sollte ins Bett gehen, um wieder klar denken zu können *lol*)
jaenicke - Di 29.04.08 21:34
Dir ist es ja jetzt anscheinend klar, was das für einen Sinn hat, aber um es nochmal für alle späteren Leser klar zu machen:
Ein Exponent, dessen Betrag kleiner als 2 ist, also -1, 0 oder 1 ist, der muss ja auch nicht hingeschrieben werden, dementsprechend passiert das nur, wenn der Betrag kleiner oder gleich 2 ist. ;-)
delfiphan - Mi 30.04.08 14:48
Ich wollte das eigentlich noch entfernen, hab's dann aber gelassen ;). Es müsste entweder ohne abs sein, oder mit, dann aber noch mit der Ausnahme, dass -1 eben doch dargestellt wird.
Da im Code keine negativen Exponenten dargestellt werden, ist's egal. Kannst es ja einfach entfernen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!