| Autor |
Beitrag |
Dibelius
      
Beiträge: 64
|
Verfasst: Di 29.04.08 17:05
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...
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
Zuletzt bearbeitet von Dibelius am Mi 07.05.08 18:16, insgesamt 1-mal bearbeitet
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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:
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
Zuletzt bearbeitet von delfiphan am Mi 30.04.08 18:37, insgesamt 2-mal bearbeitet
|
|
Dibelius 
      
Beiträge: 64
|
Verfasst: 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
      
Beiträge: 19335
Erhaltene Danke: 1751
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Di 29.04.08 19:01
Das schaffst du wohl noch selbst 
|
|
Dibelius 
      
Beiträge: 64
|
Verfasst: Di 29.04.08 20:26
indeed
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
|
|
j.klugmann
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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 
      
Beiträge: 64
|
Verfasst: 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
      
Beiträge: 19335
Erhaltene Danke: 1751
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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.
|
|
|