Autor Beitrag
Delphi-Peter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Fr 06.10.06 14:35 
Hallo ich bins nochmal.
Ich hab aber das Script noch mal ganz neu und anderst geschrieben, aber es will einfach nicht funktionieren. Wenn mehr als 2 Faktoren vorhanden sind läuft sich die while Schleife zu Tode...
Ich hab mal wieder keine Ahnung wieso und hoffe, dass ihr mir helfen könnt.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function Primzahl(zahl : cardinal): boolean;
var     flag : boolean;
        teiler : cardinal;
begin
        flag := false;
        for teiler := 2 to round(sqrt(zahl))do
        if(zahl mod teiler = 0)
        then begin
                flag := true;
                break
        end;
        if(flag)then result := false
        else result := true;
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function Faktoren(zahl : cardinal): cardinal;
var     teiler : cardinal;

begin
        for teiler := 2 to zahl do
        begin
                if(zahl mod teiler = 0)then
                begin
                        result := round(zahl / teiler);
                        break;
                end;
        end;
end;


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:
function check(zahl : cardinal) : string;
var     ergebnis : string;
        produkt, faktor, rest : cardinal;
        checkRest : boolean;

begin
        if(Primzahl(zahl) = true)then result := ' ist eine Primzahl'
        else
        begin
                checkRest := false;
                produkt := 1;
                ergebnis := ' ist keine Primzahl: 1';
                while(produkt <> zahl)do
                begin
                        if(checkRest = true)then rest := Faktoren(rest)
                        else rest := Faktoren(zahl);
                        faktor := round(zahl / rest);

                        if(Primzahl(rest) = true)then
                        begin
                                ergebnis := ergebnis + ' * ' + IntToStr(faktor) + ' * ' + IntToStr(rest);
                                produkt := produkt * faktor * rest;
                        end
                        else
                        begin
                                ergebnis := ergebnis + ' * ' + IntToStr(faktor);
                                produkt := produkt * faktor;
                                checkRest := true;
                        end;
                end;
                result := ergebnis;
        end;
end;





Das ist das alte Script:

Hallo

Ich habe eine kleine Funktion geschrieben die mir alle Primfaktoren zurückgibt. Leider gibt es bei Zahlen bei denen ein Faktor mehrmals vorkommt Fehlausgaben heraus, die ich mir nicht erklären kann. Ich hoffe ihr habt eine Idee woran das liegen könnte.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function Faktoren(zahl : cardinal): string;
var     teiler, intNeu : cardinal;
        neu : real;
        ausgabe : string;
begin
        for teiler := 2 to zahl do
        begin
                if(zahl mod teiler = 0)then
                begin
                        if(zahl = teiler)then break
                        else
                        begin
                                neu := zahl / teiler;
                                ausgabe := ausgabe + ' * ' + IntToStr(teiler);
                                intNeu := round(neu);
                                Faktoren(intNeu)
                        end;
                end;
        end;
        result := ausgabe;
end;


Beispielausgaben:

Der Anfang der Ausgabe ist übrigens außerhalb der Funktion.

10 = 1 * 2 * 5
So sollte es ja bei allen sein, aber sobald ein Faktor mehrmals vorkommt wird z.B. so etw. ausgegeben:
50 = 1 * 2 * 5 * 10 * 25
44 = 1 * 2 * 4 * 11 * 22

Ich hoffe ihr könnt mir helfen

Gruß Peter


Zuletzt bearbeitet von Delphi-Peter am Fr 06.10.06 21:17, insgesamt 1-mal bearbeitet
uwewo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 154



BeitragVerfasst: Fr 06.10.06 14:51 
In Deiner Schleife prüfst Du alle Teiler zwischen 2 und der Zahl

und das ist eben 1, 2, 5, 10 und 25 durch diese Zahlen kann man 50 teilen.

Deine Funktion mach nur das was Du ihr sagst :lol:
Delphi-Peter Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Fr 06.10.06 15:03 
OK danke
wie mache ich es, dass er die Schleife abbricht und die Funktion neu Aufrufe mit der Zahl = Zahl / Teiler ?
Wenn ich ein break einsetze gibt er nur den ersten Primfaktor aus

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
//...
intNeu := round(neu);
Faktoren(intNeu);
break
//...
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Fr 06.10.06 15:08 
sollte mit continue gehen oder?
Delphi-Peter Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Fr 06.10.06 15:17 
Und wo eürdest du das dann reinschreiben. Wenn ich es an die Stelle von break setze macht er das gleiche wie wenn kein break oder continue in der Funktion sein würde.
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Fr 06.10.06 15:26 
jaja, hast recht... ich leg mich besser wiederhin. bin einfach zu müde um zu denken :oops:
freak4fun
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 604
Erhaltene Danke: 4

Win 7 Pro
VS 2013 Express, Delphi, C#, PHP, Java
BeitragVerfasst: Fr 06.10.06 15:30 
Du musst das Faktoren(intNeu); noch irgendwie ins EndResult reinbringen, der Rückgabewert der Funtion wird nicht verarbeitet. :gruebel:

MfG
freak

_________________
"Ich werde auf GAR KEINEN Fall…!" - "Keks?" - "Okay, ich tu's."
i++; // zaehler i um 1 erhoehen
Delphi-Peter Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Fr 06.10.06 15:39 
Das hab ich mir auch überlegt aber es funktioniert nicht....
ausblenden 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:
function Faktoren(zahl : cardinal; ausgabe : string): string;
var     teiler, intNeu : cardinal;
        neu : real;
        check : boolean;
begin
        check := false;
        for teiler := 2 to zahl do
        begin
                if(zahl mod teiler = 0)then
                begin
                        if(zahl = teiler)then break
                        else
                        begin
                                neu := zahl / teiler;
                                ausgabe := ausgabe + ' * ' + IntToStr(teiler);
                                intNeu := round(neu);
                                check := true;
                                break;
                        end;
                end;
        end;
        if(check = true)then Faktoren(intNeu, ausgabe)
        else result := ausgabe;
end;
Delphi-Peter Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Sa 07.10.06 16:30 
Hallo ich bins nochmal

Ich hab das Problem jetzt gelöst. Hier der gesamte Code:

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:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
function Primzahl(zahl : cardinal): boolean; // Funktion gibt true bei einer Primzahl aus
var     flag : boolean;
        teiler : cardinal;
begin
        flag := false;
        for teiler := 2 to round(sqrt(zahl))do
        if(zahl mod teiler = 0)
        then begin
                flag := true;
                break
        end;
        if(flag)then result := false
        else result := true;
end;

function Faktoren(zahl : cardinal): cardinal; // Funktion gibt rest(= zahl / erstengefunden Faktor) der Zahl aus
var     teiler : cardinal;

begin
        for teiler := 2 to zahl do
        begin
                if(zahl mod teiler = 0)then
                begin
                        result := round(zahl / teiler);
                        break;
                end;
        end;
end;

function check(zahl : cardinal) : string; // Prüft ob Eingabe eine Primzahl ist und gibt gegebenfalls Primfaktoren zurück
var     ergebnis : string;
        produkt, faktor, rest, altRest : cardinal;

begin
        if(Primzahl(zahl) = true)then result := ' ist eine Primzahl'
        else
        begin
                produkt := 1; // Das Produkt der bisherigen Faktoren
                ergebnis := ' ist keine Primzahl: 1'; // Ausgabe String
                rest := Faktoren(zahl); // Aktueller Rest
                altRest := zahl; // Rest vor dem letzten Faktoren(zahl) - Aufruf
                while(produkt <> zahl)do
                begin
                        faktor := round(altRest / rest); // Faktor errechnen
                        if(Primzahl(rest) = true)then
                        begin
                                ergebnis := ergebnis + ' * ' + IntToStr(faktor) + ' * ' + IntToStr(rest); // Faktor und Rest zum String hinzufügen
                                produkt := produkt * faktor * rest; // EndProdukt errechnen
                        end
                        else
                        begin
                                altRest := rest; // Aktuellen Rest festhalten
                                rest := Faktoren(round(rest)); //Neuen Rest errechnen

                                ergebnis := ergebnis + ' * ' + IntToStr(faktor); // Faktor zum String hinzufügen
                                produkt := produkt * faktor; // Neues Produkt errechnen
                        end;
                end;
                result := ergebnis  + ' = ' + IntToStr(zahl); // Ausgabe
        end;
end;

procedure TForm1.UntersucheClick(Sender: TObject);
var     zahl : cardinal;

begin

try zahl := StrToInt(edZahl.Text); // Prüfen ob Eingabe eine Zahl ist
        if(zahl = 1)then laErgebnis.Caption := '1 ist keine Primzahl'
        else if(zahl = 2)then laErgebnis.Caption := '2 ist eine Primzahl'
        else laErgebnis.Caption := edZahl.Text + check(zahl);
except
        laErgebnis.Caption := 'Du musst eine Zahl eingeben';
end;

end;

end.
uwewo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 154



BeitragVerfasst: Mo 09.10.06 07:12 
Du solltest Deine Schleife noch optimieren, da es keinen Sinn macht zu versuchen
50 durch 26 zu teilen.

Also max. bis zur halben Zahl prüfen ob teilbar oder nicht.

Hoffe Du verstehst was ich meine :o