Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Arithmetisches Mittel berechnen
Marco D. - Mo 01.05.06 17:19
Titel: Arithmetisches Mittel berechnen
Hallo,
ich schreibe derzeit an einem Zensuren-Analyse-Programm. Dazu muss ich einige Male das arithmetische Mittel aus z.B. '1,2,3,,4,5,6' berechnen. Dazu habe ich mir folgende Funktion geschrieben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function TForm1.ArithMittel(str:string) : integer; var i:integer; temp:string; begin if Length(str)>0 then begin temp:=''; for i := 1 to length(str) do begin if not (str[i]=',') then temp:=temp+str[i]; end; result:=0; for i := 1 to Length(temp) do begin result:=result+strtoint(temp[i]); end; result:=result div length(temp); end; end; |
Jedoch scheinen manchmal falsche Zahlwerte rauszukommen. Kann man diese Funktion vereinfachen und nebenbei dafür sorgen, dass sie alles richtig macht?
der Berliner - Mo 01.05.06 18:29
Hallo, Also ich hab die Function mal Ausprobiert.
Die scheint doch aber richtig zu rechenen.
(1+2+3+4+5+6) DIV 6 = 3
ganz richtig währe narürlich 3,5
das liegt aber wohl am Div
gruß
Marco D. - Mo 01.05.06 18:33
Ja, eigentlich habe ich das Problem schon selber behoben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function TForm1.ArithMittel(str:string) : extended; var i:integer; temp:string; begin if Length(str)>0 then begin temp:=''; for i := 1 to length(str) do begin if not (str[i]=',') then temp:=temp+str[i]; end; result:=0; for i := 1 to Length(temp) do begin result:=result+strtoint(temp[i]); end; result:=result / length(temp); end; end; |
Manchmal kommen bei der Zensuren-Analyse aber immer noch total sinnlose Ergebnisse heraus. Aber der Fehler liegt wohl woanders :-(
aim65 - Mo 01.05.06 18:39
Auch wenn die Ausgangsziffern vom Typ Integer sind, kann das Ergebnis ja einen Dezimalbruch darstellen. Daher mußt Du "result" als Floating Point deklarieren und in Zeile 16 folgendes korrigieren:
Delphi-Quelltext
1: 2: 3: 4:
| function TForm1.ArithMittel(str:string) : double; . . result:=result / length(temp); |
Dann müssten Die Ergebnisse ok sein.
Man könnte z.B. die Source-Länge verkürzen, indem man jeden gefundenen Zahlenstring sofort in ein Integer umwandelt, aufaddiert, und dann durch Zahl der gefundenen Zifern teilt.
der Berliner - Mo 01.05.06 18:41
Hat er doch gemacht :D
siehe oben :D
gruß
Marco D. - Mo 01.05.06 18:44
aim65 hat folgendes geschrieben: |
Auch wenn die Ausgangsziffern vom Typ Integer sind, kann das Ergebnis ja einen Dezimalbruch darstellen. Daher mußt Du "result" als Floating Point deklarieren und in Zeile 16 folgendes korrigieren:
Delphi-Quelltext 1: 2: 3: 4:
| function TForm1.ArithMittel(str:string) : double; . . result:=result / length(temp); |
Dann müssten Die Ergebnisse ok sein.
|
Was meinst du mit Ausgangsziffern? Habe ich nicht verstanden, was du mir damit sagen willst.
aim65 hat folgendes geschrieben: |
Man könnte z.B. die Source-Länge verkürzen, indem man jeden gefundenen Zahlenstring sofort in ein Integer umwandelt, aufaddiert, und dann durch Zahl der gefundenen Zifern teilt.
|
Gute Idee :zustimm: Das nehme ich in die To-Do-Liste mit auf, aber jetzt will ich erstmal an dem richtigen Berechnen der Ergebnisse arbeite.
aim65 - Mo 01.05.06 18:53
@ der Berliner
Hat sich einfach überschnitten :shock:
@ Marco D.
Mit Ausgangsziffern meinte ich Deine Zensuren im String:"1,4,2,3,..." usw.
Kann es sein, daß Du im Zensurenstring evtl. mal ein Komma vergessen hast und dann so was entstand: "1,3,44,,5,222..."? Dann käme natürlich Käse heraus. :wink:
Hab jedenfalls bisher nix Falsches in Deiner Funktion gefunden.
Marco D. - Mo 01.05.06 18:58
Ich schreibe mir erstmal eine Funktion, die überprüft, ob die Zensuren richtig eingegeben wurden (X,X,X,X).
aim65 - Mo 01.05.06 19:03
Hatte ich noch vergessen:
Ich würde auf gültige Zahlen testen. Das würde sicherstellen, daß auch ein Nicht-Kommazeichen unterdrückt wird.
Marco D. - Mo 01.05.06 19:06
Einfache vom ersten Zeichen an jedes zweite durchgehen, und prüfen ob es eine Zahl ist (wie könnte man das machen?)
Marco D. - Mo 01.05.06 19:16
Geht das auch einfacher als so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function IsValidMark (C:char) : boolean; begin result:=false; if C='1' then result:=true else if C='2' then result:=true else if C='3' then result:=true else if C='4' then result:=true else if C='5' then result:=true else if C='6' then result:=true else result:=false; end; |
delfiphan - Mo 01.05.06 19:25
Delphi-Quelltext
1:
| Result := C in ['1'..'6']; |
aim65 - Mo 01.05.06 19:28
Nee, das wäre zu unsicher (z.B., wenn aus Versehen zwei Kommas kommen). Deine Rouitne ist schon ok. Hab jetzt kein Delphi offen, daher PseudoCode:
for n := 1 to length(str)
if not str[n] in ['1'..'6'] then Schmeiß-Raus
else ZahlenChar in Integer umwandeln, Counter erhöhen, Zahl aufaddieren
Ich weiß, sieht grausam aus, aber Du kriegst den Sinn wohl raus.
Kannst die Abfrage auch positiv machen, dann if und else-Inhalt vertauschen.
delfiphan - Mo 01.05.06 19:41
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:
| function calcAvg(S: String): Extended; var I, Sum: Integer; begin with TStringList.Create do try Delimiter := ','; DelimitedText := S; Sum := 0; for I := 0 to Count-1 do inc(Sum, StrToInt(Strings[I])); if Count = 0 then raise EInvalidOp.Create('Cannot calculate mean of an empty set.'); Result := Sum/Count; finally Free; end; end;
procedure TForm1.ButtonClick(Sender: TObject); var Input: String; begin Input := '1, 2, 3'; try ShowMessage(Format('Der Mittelwert lautet %.1f',[calcAvg(Input)])); except on E:Exception do MessageDlg('Fehlerhafte Eingabe.', mtError, [mbOk], 0); end; end; |
Marco D. - Mo 01.05.06 19:41
Danke! Das klappt erstmal :zustimm:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 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!