Zum Inhalt springen

Primzahlzwillinge VBA


septix

Empfohlene Beiträge

Hallo Leute,

ich habe eine Aufgabe die da lautet 2 eingegebene Zahlen als Primzahlzwilling zu identifizieren.

Dabei soll die Prüfung auf Primzahl und auf Zwilling in einer Function geschehen.

Meine erste programmierte Idee sieht wie folgt aus:


Option Explicit


Sub Primzahl()

    ' variablen deklaration

    Dim eingabe0 As Double

    Dim eingabe1 As Double

    Dim x0 As Double

    Dim x1 As Double


    'Inputbox für Eingabe + >1?


    'eingabe = Application.InputBox(prompt:="Bitte geben Sie eine Zahl ein." & _

    '"Wir werden sehen ob es sich um eine Primzahl handelt.", Type:=1)


    eingabe0 = InputBox("Zahl 1 eingeben: ")

    If eingabe0 <= 1 Then

        MsgBox ("Nur Zahlen größer 1!")

        Exit Sub

    End If


    eingabe1 = InputBox("Zahl 2 eingeben: ")

    If eingabe1 <= 1 Then

        MsgBox ("Nur Zahlen größer 1!")

        Exit Sub

    End If


    ' eingabe0 = Primzahl?

    x0 = Prim((eingabe0))


        ' Ausgabe eingabe0

    If x0 > 2 Then

        MsgBox (eingabe0 & " ist keine Primzahl")

    Else

        MsgBox (eingabe0 & " ist Primzahl")

    End If


    ' eingabe1 = Primzahl?

    x1 = Prim((eingabe1))


        ' Ausgabe eingabe1

    If x1 > 2 Then

        MsgBox (eingabe1 & " ist keine Primzahl")

    Else

        MsgBox (eingabe1 & " ist Primzahl")

    End If


    If x0 <= 2 And x1 <= 2 Then

        Call Zwilling(eingabe0, eingabe1)

    End If

End Sub


Function Prim(Param As Double) As Double


    Dim i As Double

    Dim a As Double

    Prim = 0


    ' Primzahlprüfung

    For i = 1 To Param

        a = Param / i

        If a = Int(a) Then

            Prim = Prim + 1

        End If

    Next

Exit Function

End Function


Function Zwilling(Param0 As Double, Param1 As Double) As Double

    Zwilling = Param0 - Param1

    If Zwilling = 2 Or Zwilling = -2 Then

        MsgBox "Bei " & Param0 & " und " & Param1 & " handelt es sich um ein Primzahlzwilling"

    End If

End Function

An sich funktioniert es, gibt es eventuell noch Verbessereungen die der Ein oder Andere hat?

mfg

septix

Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum verwendest du Double-Datentypen? Long wäre eher geeignet. Es kommen ja nur ganze Zahlen als Primzahlen in Frage.

Ich würde in der Funktion Prim() die Überprüfung einbauen, dass die Primzahl nicht 0 oder 1 sein kann.

Außerdem ist deine Primzahlüberprüfung von 1 bis Param.

1. Ist 1 als Startwert nicht nötig, da du ja weißt dass es immer durch 1 teilbar ist.

2. Musst du doch nur bis zur Hälfte der angegebenen Zahl testen.

Beispielweise hast du die Zahl 51. Du musst nur die möglichen Teiler 2 (kleinster möglicher Teiler) bis 25 testen, denn 25 * 2 ist 50 und 26 * 2 ist 52. (Primzahlenzerlegung... 2 ist die kleinste Primzahl).

Außerdem reicht es Modulo-Division zu nutzen. Ist eine Zahl durch eine andere Zahl vollständig teilbar, dann ergibt das Rest 0. Dadurch musst du nur für den Parameter einmalig den Int wert ermitteln und nicht jedesmal in der schleife.

Außerdem kannst du den Absoluten Wert der Differenz der beiden Primzahlen verwenden. Dann musst du nur noch einen Vergleich machen.

Hab kein VB installiert. Kann also nicht testen.

Option Explicit


Sub Primzahl()

    ' variablen deklaration

    Dim eingabe0 As Long

    Dim eingabe1 As Long


    'eingabe = Application.InputBox(prompt:="Bitte geben Sie eine Zahl ein." & _

    '"Wir werden sehen ob es sich um eine Primzahl handelt.", Type:=1)


    eingabe0 = InputNumber()


    eingabe1 = InputNumber()


    If ABS(Param0 - Param1) = 2

        MsgBox "Bei " & eingabe0 & " und " & eingabe1 & " handelt es sich um ein Primzahlzwilling"

    End If

End Sub


Function Prim(Param As Long) As Boolean


    Dim i As Long


'Alle Zahlen kleiner gleich 1 können nicht Primzahlen sein

If Param <= 1 Then

Return false

End if


    ' Primzahlüberprüfung

    For i = 2 To CLng(Param/2)

'Wenn ohne Rest dividiert werden kann dann ist ein Teiler gefunden, und somit keine Primzahl

        If (Param % i) = 0 Then

            return false

        End If

    Next


Return true

End Function


Function InputNumber() As Long 

dim inputValue as Long = 0

        inputValue = CLng(InputBox("Zahl eingeben: "))

    while Not Prim(inputValue) 

        MsgBox ("Ist keine Primzahl!")

        inputValue = CLng(InputBox("Zahl eingeben: "))

    End while

return inputValue

End Function

Bearbeitet von Aras
Link zu diesem Kommentar
Auf anderen Seiten teilen

Also der schnellste Algorithmus den ich kenne ist der Sieb des erathostenes (ich glaub so oder so ähnlich hieß der Kerl) damit kannst du sehr schnell alle primzahlen von x bis y herausfinden wobei y eine sehr hohe Zahl sein kann und du musst den Algorithmus nur bis wurzel(y) durchlaufen

Link zu diesem Kommentar
Auf anderen Seiten teilen

An sich funktioniert es, gibt es eventuell noch Verbessereungen die der Ein oder Andere hat?
Deine Funktion Zwilling ist verbesserungsfähig. Die Ausgabe passt nicht da rein, und falsch ist sie (im Kontext der Funktion) auch.

Die Funktion prüft, ob es sich bei Param0 und Param1 um Zwillinge (also Abstand 2) handelt. Das ist so weit richtig. Bei erfolgreicher Prüfung gibt die Funktion jedoch aus, dass es sich um Primzahlzwillinge handelt. Das funktioniert an dieser Stelle nur, weil du vorher einen Primzahltest durchgeführt hast, und ansonsten diese Funktion gar nicht aufrufst.

Die Funktion sollte gar nichts ausgeben, sondern nur über ihren Rückgabewert (den du gar nicht verwendest) das Ergebnis der Prüfung signalisieren. Und das sollte auch nicht irgendein Wert sein, sondern True oder False. Letzteres gilt übrigens auch für die Funktion Prim.

Link zu diesem Kommentar
Auf anderen Seiten teilen

2. Musst du doch nur bis zur Hälfte der angegebenen Zahl testen.

Beispielweise hast du die Zahl 51. Du musst nur die möglichen Teiler 2 (kleinster möglicher Teiler) bis 25 testen, denn 25 * 2 ist 50 und 26 * 2 ist 52. (Primzahlenzerlegung... 2 ist die kleinste Primzahl).

Bis zur Wurzel der Zahl reicht, also bei 51 würde 8 bereits ausreichen, da Wurzel(51)=7,...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Stimmt. Bis zur Wurzel der zu untersuchenden Zahl.

Auf Wikipedia steht ja auch wie man Primzahlzwillinge untersuchen könnte. (6n-1) (6n+1).

Zuerst überprüfen ob die Differenz der beiden Zahlen 2 ergibt, und der größeren Zahl 1 abziehen und auf die Teilbarkeit durch 6 Überprüfen. Natürlich kann man so nicht 3 und 5, 5 und 7 überprüfen.

Weiß garnicht ob das dann immer Primzahlzwillinge ergibt, aber wäre schon ein schnellerer Algo

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zuerst überprüfen ob die Differenz der beiden Zahlen 2 ergibt, und der größeren Zahl 1 abziehen und auf die Teilbarkeit durch 6 Überprüfen.

Sorry, wieder falsch. Nicht jede dieser Zahl (z.B. 25), die Nachfolger einer durch 6 teilbaren zahl ist, ist auch Primzahl.

Wenn du eine Primzahl hast (und das willst du erst untersuchen), dann ist sie darstellbar durch 6n-1 oder 6n+1, also bei Primzahlzwillingen ist die kleinere Zahl 6n-1, die grössere Zahl 6n+1. Aber (nochmal), nicht jede Zahl, die das erfüllt, ist auch Primzahl.

Link zu diesem Kommentar
Auf anderen Seiten teilen

nur weil du Sorry schreibst, klingt es nicht weniger überheblich.

Hab ja auch im letzten Satz geschrieben dass es überprüft werden muss, ob es wirklich Primzahlzwillinge ergibt.

Das hat nix mit Überheblichkeit zu tun.

Der Test auf 6n+1 ist für die Fragestellung nunmal sinnlos. Es ist somit auch kein schneller Test.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Sorry, du hast keine Manieren und solltest deine Art und Weise überdenken.

Fühlt sich besser an mit "Sorry" einzuleiten. Kann man die Beleidigung als besser kaschieren. Nicht wahr?

Der Test ob die Zahl zwischen den beiden Primzahlen durch 6 teilbar ist, ermöglicht es einen kostengünstigeren Algorithmus zu programmieren.

Wenn die Zahl zwischen den zwei möglichen Primzahlen durch 6 teilbar ist, dann macht man die Überprüfung ob die beiden Zahlen Primzahlen sind. Ausnahme 3 und 5.

Function PrimTwin(Param1 As Long, Param2 As Long) As Boolean


    Dim i As Long


'Überprüfe Abstand

If ABS(Param1 - Param0) <> 2 then

return false

end if


'Überprüfe ob die Ausnahme 3 und 5 sind

if Not ((Param1 = 3 AND Param0 = 5) OR Param0 = 3 AND Param1 = 5) then


'Überprüfe ob Zahl dazwischen durch 6 teilbar ist

if (Param1 > Param0) then

  if ((Param1 - 1) % 6) <> 0 then

     return false

  end if


else

  if ((Param0 - 1) % 6) <> 0 then

     return false

  end if

end if 


end if


If not (Prim(Param1) AND Prim(Param2)) then

return false

end if


Return true

End Function

Link zu diesem Kommentar
Auf anderen Seiten teilen

@MartinSt

Ich habe keinen VB auf meinem Rechner und habe den Code aus dem Kopf geschrieben.

Param2 ist offensichtlich Param1.

i ist aus dem vorherigen Code entstanden

Und was der Code macht sollte dir als Programmierer leicht fallen zu verstehen, da es ziemlich trivial ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...