Autor Beitrag
Dibelius
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: 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...

ausblenden volle Höhe 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  // lineare Fkt.
        if (a=0then begin
          if (b=0then result:= sfx+' = 0';
          if (b<>0then result:= Format(sfx+' = %s', [b]);
        end
        else begin  // a<>0
          if (b=0then result:= Format(sfx+' = %sx', [a]);
          if (b<0then result:= Format(sfx+' = %sx %s', [a,b]);
          if (b>0then result:= Format(sfx+' = %sx +%s', [a,b]);
        end;
      end;
    2:begin  // quadr. Fkt.
        if (a=0then begin
          if (b=0then begin
            if (c=0then result:= sfx+' = 0';
            if (c<>0then result:= Format(sfx+' = %s', [c]);
          end
          else begin  // b<>0
            if (c=0then result:= Format(sfx+' = %sx', [b]);
            if (c<0then result:= Format(sfx+' = %sx %s', [b,c]);
            if (c>0then result:= Format(sfx+' = %sx +%s', [b,c]);
          end;
        end
        else begin  // a<>0
          if (b=0then begin
            if (c=0then result:= Format(sfx+' = %sx²', [a]);
            if (c<0then result:= Format(sfx+' = %sx² %s', [a,c]);
            if (c>0then result:= Format(sfx+' = %sx² +%s', [a,c]);
          end
          else begin  // b<>0
            if (b<0then begin
              if (c=0then result:= Format(sfx+' = %sx² sx', [a,b]);
              if (c<0then result:= Format(sfx+' = %sx² %sx %s', [a,b,c]);
              if (c>0then result:= Format(sfx+' = %sx² %sx +%s', [a,b,c]);
            end;
            if (b>0then begin
              if (c=0then result:= Format(sfx+' = %sx² +sx', [a,b]);
              if (c<0then result:= Format(sfx+' = %sx² +%sx %s', [a,b,c]);
              if (c>0then result:= Format(sfx+' = %sx² +%sx +%s', [a,b,c]);
            end;
          end;
        end;
      end;
    3:begin  // Fkt. 3. Grades
        //
      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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  case FuncType of
    1:begin  // lineare Fkt.
        if (a=0then begin
          if (b=0then result:= sfx+' = 0';
          if (b<>0then result:= Format(sfx+' = %s', [b]);
        end
        else begin  // a<>0
          if (b=0then result:= Format(sfx+' = %sx', [a]);
          if (b<0then result:= Format(sfx+' = %sx %s', [a,b]);
          if (b>0then result:= Format(sfx+' = %sx +%s', [a,b]);
        end;
      end;

==>
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  case FuncType of
    1:begin  // lineare Fkt.
        if (a=0then begin
          if (b=0then result:= sfx+' = 0'
          else if (b<>0then result:= Format(sfx+' = %s', [b]);
        end else begin  // a<>0
          if (b=0then result:= Format(sfx+' = %sx', [a])
          else if (b<0then result:= Format(sfx+' = %sx %s', [a,b])
          else if (b>0then result:= Format(sfx+' = %sx +%s', [a,b]);
        end;
      end;


Achso, und diesen Teil:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
else begin  // a<>0
          if (b=0then result:= Format(sfx+' = %sx', [a])
          else if (b<0then result:= Format(sfx+' = %sx %s', [a,b])
          else if (b>0then 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: 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:
ausblenden volle Höhe 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 <> 1or (AExponent = 0then
      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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19335
Erhaltene Danke: 1751

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 29.04.08 19:01 
Das schaffst du wohl noch selbst ;)
Dibelius Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: 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:

ausblenden 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



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19335
Erhaltene Danke: 1751

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: 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.