Autor |
Beitrag |
Marco D.
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Mo 01.05.06 17:19
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?
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
der Berliner
      
Beiträge: 417
Win Xp Home
delphi 2005
|
Verfasst: 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ß
_________________ [b]Ich weiß nicht immer, wovon ich rede. Aber ich weiß, dass ich recht habe.[b]
|
|
Marco D. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: 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 
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: 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
      
Beiträge: 417
Win Xp Home
delphi 2005
|
Verfasst: Mo 01.05.06 18:41
Hat er doch gemacht
siehe oben
gruß
_________________ [b]Ich weiß nicht immer, wovon ich rede. Aber ich weiß, dass ich recht habe.[b]
|
|
Marco D. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Mo 01.05.06 18:44
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mo 01.05.06 18:53
@ der Berliner
Hat sich einfach überschnitten
@ 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.
Hab jedenfalls bisher nix Falsches in Deiner Funktion gefunden.
|
|
Marco D. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: 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).
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: 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. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: 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?)
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
Marco D. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: 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; |
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 01.05.06 19:25
Delphi-Quelltext 1:
| Result := C in ['1'..'6']; |
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 01.05.06 19:41
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; |
Zuletzt bearbeitet von delfiphan am Mo 01.05.06 19:42, insgesamt 1-mal bearbeitet
|
|
Marco D. 
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Mo 01.05.06 19:41
Danke! Das klappt erstmal 
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
|