![]() |
Teilermenge ermitteln
Hallo,
in meinem aktuellen Projekt benötge ich die ![]() Also z. B. T9={1,3,9} Klar kann ich diese mit einer Schleife errechnen; das finde ich aber nicht so schön bzw. Schleifen dauern bei großen Zahlen einfach zu lang... Ich habe schon gesucht, aber nichts gefunden: Gibt es ein rechnerisches Verfahren, um die Teilermengen bzw. deren Anzahl zu berechen? Besonders die Anzahl ist mir wichtig. Vielen Dank im voraus |
Re: Teilermenge ermitteln
Bisher gibt es keine besseren Verfahren, ansonsten könnte RSA u. ä. einpacken, da die darauf basieren, dass man eine Zahl nur per Brute-Force faktorisieren (in die Teiler zerlegen) kann. Nützlich könnten hier Lookup-Tables oder Primfaktorzerlegung sein (dazu denk ich mir noch was aus).
|
Re: Teilermenge ermitteln
Ich habe heute nochmal meinen Mathelehrer gefragt und er redete auch etwas über Primfaktorzerlegung.
Genaueres konnte er mir aber auch nicht sagen... |
Re: Teilermenge ermitteln
Bei der PFZ zerlegt man eine Zahl in die Primfaktoren. Am Ende steht dann in etwa 12=2*2*3. Die Teiler der Zahl sind die Primzahlen selber und alle Produkte aus den Primzahlen. Die Produkte per Function auszurechnen, das ist das Interessante (Frage am Rande: Wie erhalte ich das erste Element eines Arrays, welches dann auch entfernt wird?)... Vorteil (oder auch nicht) der PFZ gegenüber der direkten Bestimmung der Teiler: Laufzeit sqrt(n)+Produktbildung gegen n/2
|
Re: Teilermenge ermitteln
wie wäre es mit Rekursion, so haben wir das in der Schule gemacht!
|
Re: Teilermenge ermitteln
Zitat:
|
Re: Teilermenge ermitteln
Das ist schonmal total falsch, du kannst jede rekursive Lösung iterativ machen (teilweise ziemlich umständlich, z. B. beim durchgehen der Ordner auf der Festplatte oder alle Wurzeln eines Trees).
Aber iterative Lösungen kannst du absolut nicht alle zu einer rekursiven machen. |
Re: Teilermenge ermitteln
Zitat:
|
Re: Teilermenge ermitteln
@CLRS530:
Delphi-Quellcode:
=
for i := 1 to 5 do
maches (i);
Delphi-Quellcode:
;)
procedure recurse (i: integer)
begin maches (i); if i < 5 then recurse (i + 1); end; recurse (1) |
Re: Teilermenge ermitteln
Zitat:
![]() Und wenn du schon dabei bist, dann zeig mir auch bitte eine Iterative Funktion, die sich nicht in eine Rekursion umwandeln lässt. |
Re: Teilermenge ermitteln
Jeder rekursive Algorithmus ist nichts anderes als eine Schleife + Stack als Zwischenspeicher (vereinfacht ausgedrückt), also kannst Du dein Ackermännchen doch einfach mit Arrays lösen, oder nicht?
Aber ob es iterative Algorithmen gibt, die sich partout nicht rekusriv formulieren lassen....? |
Re: Teilermenge ermitteln
Zitat:
f := f(f(x)) lösen sollte. edit: ich bin mir ziemlich sicher dass es so ist wie ich es eingangs gesagt hatte: Iterativ -> Rekursiv: immer möglich Rekursiv -> Iterativ: manchmal, aber nicht immer möglich |
Re: Teilermenge ermitteln
Zitat:
Und wenn dich das nicht überzeugt, dann denk dir einfach, das die CPU per se iterativ arbeitet und jeden noch so rekursiven Mist als einfache Abfolge von Sprüngen (ok, ein bisserl gerechnet wird auch) abarbeitet. Insofern ist es -ich sags nochmal- banal. Aber: Sich für jede rekursive Funktion eine entsprechende Iterative auszudenken, ist schwierig, da stimme ich Dir zu. Von der Seite aus gesehen würde ich das auch anzweifeln. Dein Beispiel f:= f(f(x)) ist auch rekursiv nicht lösbar (-> Endlosschleife). |
Re: Teilermenge ermitteln
Dann liefer doch mal eine iterative Lösung für folgendes Problem:
Du hast eine Menge mit n Elementen und möchtest alle Kombinationen mit 1,2,3,...,n-1 Elementen erhalten Rekursiv geht relativ einfach, iterativ (fast) unmöglich, oder? |
Re: Teilermenge ermitteln
Hi folks,
im Informatikstudium lernt man, dass Iteration und Rekursion äquivalente Lösungsverfahren sind. Das eine lässt sich stets in das andere umwandeln. Während der Weg Iteration nach Rekursion trivial ist (z.B. tail recursion) ist der umgekehrte Weg mitunter haarig, unsinnig, sinnverschleiernd - aber auf jeden Fall möglich. Grüße vom marabu |
Re: Teilermenge ermitteln
Gibt es denn mittlerweile eine rein iterative Lösung zun den "Türmen von Hanoi"? Zu meiner Schulzeit jedenfalls war imho noch keine bekannt. (Zumindest meinte dies unserer (entgegen der landläufigen Üblichkeit) relativ gute Info-Lehrer...)
|
Re: Teilermenge ermitteln
Hi dizzy,
die Towers of Hanoi sind ein relativ altes Kinderspielzeug. Ich habe jetzt keine Geschichtsforschung betrieben, aber möchte trotzdem behaupten, dass jede rekursive Implementierung des Lösungsalgorithmus jünger ist als die iterative, deren Existenz die Informatiker postulieren. Mir persönlich reicht die Gewissheit, dass es geht, aber wer genügend Zeit für zweckfreies Tun erübrigen kann, der kann sich ja an der Implementierung der iterativen Lösung versuchen. Der Algorithmus wird z.B. von ![]() Grüße vom marabu |
Re: Teilermenge ermitteln
Ist doch ganz einfach:
Delphi-Quellcode:
for i:=1 to zahl do
if zahl mod i=0 then begin {Wenn du die Teiler in einem Array of integer brauchtst:} setlength(teilerarray,length(teilerarray)+1); teilerarray[length(teilerarray)]:=i; {oder als Liste:} teilerliste.add(i); end; |
Re: Teilermenge ermitteln
Informatiker wollen's aber nicht einfach, sondern schnell :wink: . Und in diesem Fall ist eine Primfaktorzerlegung sicher schneller.
PS: Du solltest dein Array zur Performancesteigerung lieber um 172% vergrößern *g* . |
Re: Teilermenge ermitteln
Zitat:
Delphi-Quellcode:
Nachtrag:
Procedure Permutations (aString : String);
Var d : Array Of Integer; g, j, i, n, v : Integer; p,c : String; Begin n := Length (aString); setlength (d,n+1); d[1] := 1; For i := 2 to n do d[i] := i * d[i-1]; For i := 0 to d[n]-1 do begin c := aString; p := ''; v := i; for j:=n-1 downto 1 do begin g := j - (v div d[j]) + 1; p := p + c[g]; delete (c, g, 1); v := v mod d[j]; End; p := p + c; memo1.lines.Add (p); End; End; Man kann den Algorithmus auch so umschreiben, das man direkt die N.te Permutation ausrechnet:
Delphi-Quellcode:
Nicht sonderlich rekursiv, aber trotzdem schnell. Basiert im Übrigen auf der Inversen und Graycodes.
Function NthPermutation (aString : String; aCount : Integer) : String;
Var d : Array Of Integer; g, i, n : Integer; Begin n := Length (aString); setlength (d, n); d[1] := 1; For i := 2 to n - 1 do d[i] := i * d[i-1]; Result := ''; for i := n-1 downto 1 do begin g := (aCount div d[i]) + 1; Result := Result + aString[g]; delete (aString, g, 1); aCount := aCount mod d[i]; End; Result := Result + aString; End; |
Re: Teilermenge ermitteln
da sagt man einmal rekusion und schon hat man ne Welle losgetreten!
Ich weiß zwar nicht warum, aber mein Info lehrer will fast immer das wir Probleme rekursiv lösen! Gibt es einen Vorteil wenn man es über Wiederaufrufe macht? |
Re: Teilermenge ermitteln
Als Faustregel kann man formulieren: rekursiv definierte Probleme lassen sich über rekursive Algorithmen sehr elegant lösen, performanter ist in der Regel der iterative Algorithmus.
marabu |
Re: Teilermenge ermitteln
Zitat:
@marabu: wieder was dazu gelehrnt. gibt es denn ein standardverfahren, wie man eine rekursive implementierung in eine iterative umwandelt? |
Re: Teilermenge ermitteln
Hi BlackJack,
ein einziges Standardverfahren kann es nicht geben, da die Rekursion selbst Varianten kennt - nicht jede Rekursion ist linear und selbst die linearen weisen nicht ausnahmslos eine tail recursion auf. Die Schematisierung des Transformationsprozesses interessiert die Informatiker auch heute noch, z.B. bei der Implementierung funktionaler Sprachen (Lisp, Hope, Miranda, Haskell). Magst du einen kleinen Einblick? ![]() marabu |
Re: Teilermenge ermitteln
Jede rekursive Funktion wird und muß in eine iterative umwandelbar sein.
Es gibt aber iterative Funktionen die nicht rekursiv gelösst werden können. Die rekursive Schreibweise ist nur eine andere Form eines iterativen Verfahrens. Der einzigste Unterschied liegt in der meist einfacheren Begreiflichkeit der rekursiven Verfahren für den Menschen. Für ds oben angesprochene Problem der Kombinatorik hätte sich auch ein Blick in die CodeLib gelohnt. Dort findest du bestimmt einige Sourcen. Gruß Hagen |
Re: Teilermenge ermitteln
Zitat:
![]() |
Re: Teilermenge ermitteln
Hallo Hagen,
Zitat:
Zitat:
Freundliche Grüße vom marabu @BlackJack: In dem von mir hier zitierten Buch versucht der Autor einige Vorgehensweisen zur Schematisierung der Transformation zu vermitteln. |
Re: Teilermenge ermitteln
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz