Hi Hagen,
Zitat von
negaH:
@Secure:
sorry aber [...] halte ich fr ziemlich übel.
1.) Du vereinfachst durch eigene Annahmen die gewünschte Funktionsweise des Programmieres, indem du enifach mal davon ausgehst das man eh nur Zahlen bis 2^31 testen möchte, statt eben wie im Original mit Int64 zu rechnen. Das ist wohl sehr schlechter Stil. Die Aufgabe des programmieres ist es die Forderungen EXAKT umzusetzen.
Was war denn die Forderung? Ich habe nur gelesen, dass es sich um ein Programm zum Primfaktorzerlegung handelt und gesehen, dass der Autor die Zahlen über ein Edit via StrToInt einliest. Folgedem ist ein integer ideal, da er - im Gegensatz zu einem int64 - schneller berechnet wird und alle Werte, die StrToInt zurückliefern kann, aufnehmen kann. Die Aufgabe, die ich mir beim Programmieren setze, ist, optimal zu Programmieren, in erster Linie in Hinblick auf Geschwindigkeit, im zweiten Hinblick auf Ästhetik.
Zitat von
negaH:
2.) dein Source ist fehlerhaft. Was ist mit 0, oder -1 oder allen Zahlen bis -(2^31-1). Übergibt man deiner Funktion einen Integer im Wertebereich der Integer von -2^31 bis 2^31 dann macht sie defacto exakt 50% Fehlerhafte Ausagen.
OK, habe ich verbessert.
Zitat von
negaH:
3.) dein Schreibstil, hm naja. Das Besondere in PASCAL ist es das man Gorß/Klein Schreibung als Mittel zu besseren Lesbarkeit einsetzen kann. Du verzichtest darauf indem du alles klein schreibst. Damit verzichtest du auf Übersichtlickeit.
Großschreiben wird allgemein als Schreien angesehen, und ich schreie meinen Compiler/Computer/wasauchimmer nicht an
. Außerdem verwende ich sehr wohl Groß-/Kleinschreibung, allerdings hauptsächlich bei Variablen- und Funktionsnamen, dort, wo es eben sinnvoll ist.
Zitat von
negaH:
4.) N. Wirth hat mit Absicht die "Gültigkeit eines Source Blocks" visuell grafisch auch als eingerückter Block mit einem senkrecht untereinander stehendem BEGIN und END eingeführt. Es ist also essentiell das BEGIN und END auf gleicher Einrückungsebene zu schreiben.
Ich finde, dass sich der Quelltext dadurch nur um eine weitere Zeile aufbläht. Logisch ist die genaue Einteilung mit begin/end ohnehin für Menschen nicht (IMO): Schließlich ist es ja egal, wie viele Anweisungen danach folgen (nach einer if-Bedingung zB), es muss nur dem Compiler genau gesagt werden.
Zitat von
negaH:
5.) was nun ? IstPrim() oder IsPrime() ? aber nicht IsPrim() das ist denglish.
Wenn du genau hinschaust, wirst du feststellen, dass ich IstPrim geschrieben habe.
Zitat von
negaH:
6.) in der Mathemtik ist es üblich N als Synonym für eine Natürlich Zahl zu betrachten, so wie R für rationelle Zahlen etc.pp.
Ich bin Programmierer und kein Mathematiker.
Zitat von
negaH:
7.) Sonderfall 1 ist zu wenig und berücksicht eben nicht negative Zahlen
Hast du mir doch in 2.) schon gesagt?
Zitat von
negaH:
8.) die Berechnung in for X := 0 to Trunc(Sqrt(n)) ist zwar auf Grund des Delphi Compilers möglich sollte aber aus Sicht eines Standard PASCAL Codes vermieden werden. Unter Umständen, bei erweiterte PASCAL Dialekten mit einer for i to x step y Syntax ist nämlich x als Schleifenendebedingung dynamisch veränderbar.
Ich programmiere Delphi, kein Pascal.
Zitat von
negaH:
9.) wenn es geht sollte man immer auf unnötige Sprachkonstruke verzichten und statt dessen mit "mathematischen" Zuweisungen arbeiten.
Hast du dafür ein konkretes Beispiel?
Zitat von
negaH:
10.) wenn es geht exit/goto/continue vermeinden
Warum? Es ist doch die effizienteste Methode, hier aus der Schleife zu springen, oder sehe ich das falsch?
Zitat von
negaH:
11.) man muß nur mit ungeraden Zahlen die Trialdivision durchführen. Da es aber in Delphi keine for i tox step y Schleife gibt müsste man sich behelfen mit for x := 2 to Trunc(Sqrt(N)) div 2 do und mit if N mod (i*2+1) = 0 arrbeiten, um eben den offensichtlichen mathematischen Erfordernissen gerecht zu werden. Es geht hier um Exaktheit in der Programmier Arbeit die man leistet. Allerdings ist eine solche Zähleschleife wesentlich schlechter zu verstehen als eine while Schleife. In deinem Falle testet deine Funktion die Zahl N doppelt so häufig als es nötig wäre, ergo Effizienzeinbußen.
Hmm, da kann' ich so spontan nicht zustimmen. Was ist zum Beispiel mit 8? Die Wurzel von 8 ist 2, das dann nochmal geteilt durch 2 ist 1 und deine Schleife würde gar nicht ausgeführt!
Ich hab' meinen Source verbessert (war übrigens auf Grund von zwei Tippfehlern vorher nicht lauffähig):
Delphi-Quellcode:
function IstPrim(const n:integer):boolean;
var x:integer;
begin
// Sonderfälle beachten
if (n <= 1) then begin
result:=false;
exit;
end;
result:=true;
for x:=2 to Trunc(Sqrt(N)) do
if ((n mod x) = 0) then begin
result:=false;
exit;
end;
end;
// eine meiner Lieblingsfunktionen ;)
// bildet das (<condition>?<true>:<false>)-Konstrukt aus C/PHP nach
function iif(const Condition:boolean; const IfTrue,IfFalse:string):string;
begin
if (Condition) then
result:=IfTrue
else result:=IfFalse;
end;
// integer: siehe oben
procedure Zerlegen(var OutputLabel:TLabel; const n:integer);
var x:integer;
begin
x:=2;
while ((n mod x) <> 0) do
Inc(x);
// Korrektur: OK, so schwachsinnig war sie doch nicht. Hab' mich verlesen.
OutputLabel.Caption:=OutputLabel.Caption+iif(length(OutputLabel.Caption) > 0,'*','')+IntToStr(x);
if (not IstPrim(n div x)) then
Zerlegen(OutputLabel,n div x);
m:=m*x;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
m:=1;
label2.Caption:='';
if (IstPrim(strtoint(edit1.Text))) then
Label2.Caption:=edit1.Text+' ist eine Primzahl!'
else begin
Zerlegen(Label2, StrToInt(Edit1.Text));
Label2.Caption:=Label2.Caption+'*'+IntToStr(StrToInt(Edit1.Text) div m);
end;
end;
cu