Swift-Rekursion

13. Juli 2019 21:39 Uhr - Franz

Hat jemand in Swift ein Beispiel einer Rekursion?

Ich probiere die ganze Zeit den Algorithmus der Fakultät heraus zu bekommen. Anscheinend funktioniert das in Pascal anders. Ich habe auch schon im Internet nachgesehen und der Code stimmt. Es kann daher nur an der Formulierung des Codes liegen.

Kann mir da jemand weiter helfen?

Lieber Franz,

wieso googelst Du denn so einfache Fragen nicht? Nimm Google und tippe "calculate factorial in swift" (OK, du musst vorher "Fakultät" in einem Wörterbuch nachschlagen -> www.leo.org; wobei es sogar mit "calculate faculty in swift" funktioniert!).

Das entsprechende Kapitel im Swift-Handbuch wäre: https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html

Hier meine Version nur für Dich, ohne "*=" oder "-=" Operatoren und bei der die Zahl mit ihrem jeweiligen Vorgänger multipliziert wird. Genauso richtig und noch weniger Codezeilen braucht man, wenn man von 1 hochzählt bis zur Zahl (siehe Google-Ergebnis: http://codecry.com/swift/factorial-of-a-number)

 

func fakultaet(_ zahl:Int) -> Int {

    var aktuelleZahl = zahl

    var ergebnis = aktuelleZahl

    aktuelleZahl = aktuelleZahl - 1

    

    while aktuelleZahl > 0 {

        ergebnis = ergebnis * aktuelleZahl

        aktuelleZahl = aktuelleZahl - 1

    }  

    return ergebnis

}

print(fakultaet(5))

Viele Grüße,

mabi 

@mabi99

Danke mabi.

Wie ich schreibe, habe ich gegoogelt. Allerdings sind fast alle Algoritmen entweder für  java oder C. Unter Swift oder Fakultät mit Swift bin ich nicht fündig geworden. Deswegen schreibe ich hier.

Der Begriff "Fakultät" bzw. seine Berechnung ist mir bekannt. Ebenso die Control Flow. War gut gemeint von Dir. Dein Beispiel war mir ebenfalls im Kopf aber habe es nicht probiert weil es mir um die Rekursion im engeren Sinn geht. Dein Beispiel ist die Iterative Methode, mein Versuch war die Rekursive Methode. Der eingegebene Code war soweit in Ordnung, nur der Selbstaufruf meldete einen Fehler. Es kann sich nur um einen kleinen Fehler handeln? Wahrscheinlich stehen schon wieder zu viele Bäume herum.

 

Lieber Franz,

wenn Du das schon in Java gefunden hast, dann ist es doch wirklich nur noch, das Ganze an drei, vier Stellen in Swift-Syntax zu bringen... Aber das mach ich doch gern für dich:

 

func rekursiveFakultät(_ zahl:Int) -> Int {

    if zahl > 1 {return zahl * rekursiveFakultät(zahl-1)}

    else {return 1}

}

viele Grüße,

mabi

 

Hallo mabi!

Danke, daß Du mir schon wieder die Arbeit abgenommen hast. Es war halt wie immer, daß zu viele Bäum herum gestanden sind.

Das mit den Umlauten ist wirklich etwas neues. Darüber habe ich in keinem Video oder anderen Informationen etwas gehört oder gelesen.

Würde mich freuen wenn ich Deine Hilfe wieder einmal in Anspruch nehmen darf.

 

Habe  plötzlich ein Problem beim Start des Simulators. Habe die Views entsprechend gestaltet und gestartet. Es zeigte im Simulator alles korrekt an. Als ich die entsprechenden Outlets bzw. Actions erstellen wollte  zeigte es im Simulator nur ein weißes Fenster und bei Xcode erscheint "AppDelegate.Swift" mit einer Fehleranzeige.

class AppDelegate: UIResponder, UIApplicationDelegate { = Thread 1: signal SIGABRT
und im Debugger Navigator Thread 1/Punkt 20 "main". Im Debugger Area steht unter anderem:
 

2019-07-20 16:55:19.142454+0200 Fakultät[94874:46286125] libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.

2019-07-20 16:55:19.218566+0200 Fakultät[94874:46286125] Unknown class _TtC9Fakultät14ViewController in Interface Builder file.

2019-07-20 16:55:19.250933+0200 Fakultät[94874:46286125] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x7fb111611840> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key eingabeFeld.'

und zum Schluß

libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

 Ich nehme an, daß mit der View-Gestaltung etwas nicht stimmt. Was habe ich falsch gemacht bezogen auf die Fehlermeldung? Werde das Layout nochmals machen bzw. die Constraints neu setzen aber trotzdem würde mich die Fehlermeldung interessieren.

Liebe Grüße
Franz

Ich habe im Netz gesucht und zwei interessante Videos gefunden. Vielleicht kann es auch jemand anderer gebrauchen und will es niemanden vorenthalten.

"https://learnappmaking.com/sigabrt-xcode-swift/
https://www.youtube.com/watch?v=qWqpkJZMYiE"

Sie lösen nur zum Teil das Problem. Ich kann die Verknüpfung löschen und sodann funktioniert die Darstellung im Simulator wieder. Sobald ich wieder eine Verknüpfung in ViewController.swift erstelle bekomme ich wieder dieselbe Meldung. Ich habe daher ein neues Projekt erstellt und nur ein einfaches Label aus dem Object Library genommen. Ohne Formatierungen, etc., um eventuelle Fehlerfaktoren zu vermeiden, habe ich eine Verknüpfung erstellt und trotzdem bekomme ich die Meldung. Es muß daher also an etwas anderem liegen. Hat wirklich keiner eine Idee?

Hi Franz, 

 

sorry, dass ich nicht früher geschrieben hab– ich habe da aber leider keine Idee, woran es liegen kann. Einen Versuch wert wäre es, die Umlaute doch sicherheitshalber rauszunehmen. Der Swift-Compiler selber hat damit wie Du gesehen hast keine Probleme, aber um auf Nummer sicher zu gehen, lass sie lieber raus. Du bekommst ja einen Fehler, der sagt Unknown class bzw. Unknown key, was schon daran liegen könnte, dass das Unicode-mapping da nicht richtig funktioniert. Probier's einfach mal aus (am besten in einem ganz frische Projekt).

 

Viele Grüße und viel Glück,

mabi

 

Habe keine Umlaute. Habe ein neues Projekt erstellt wie oben geschrieben und ein nackertes Label. Trotzdem bekomme ich den Fehler. Wenn ich lediglich den UI starte bekomme ich diese Meldung:

2019-07-28 11:43:02.916165+0200 Übungsprojekt[17410:6538506] libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.

2019-07-28 11:43:03.081901+0200 Übungsprojekt[17410:6538506] Unknown class _TtC14Übungsprojekt14ViewController in Interface Builder file.

Könnte da die Ursache liegen? Außerdem habe ich vor der Erstellung Xcode mit AppCleaner komplett gelöscht und neu installiert.

Wie ich sehe kann man hier keine PM-Post verschicken, sonst hätte ich Dir den gesamten Code geschickt. Du verstehst es als Programmierer besser die Fehlermeldung mit dem englischen Video zu vergleichen und zu interpretieren.

Liebe Grüße
Franz
 

Mein Gott Walter, eh mabi99.

Ich habe ja oben geschrieben, daß ich lediglich ein Label erstellt habe. Da kommt sicherlich nirgendwo ein Umlaut vor. Als Du mir das geschrieben hast, habe ich es gesehen, daß der Name des Projektes mit "Ü" geschrieben wurde. Wollte den Namen ändern aber dann funktioniert das Programm nicht mehr. Ich habe also ein neues Projekt ohne Umlaut geschrieben und siehe da, es funktioniert. Es war anscheinend lediglich der Name. Endlich kann ich wieder weiter üben. Manchmal sind es wirklich blöde Fehler.

Bin Dir zum Großen Dank verpflichtet.

Hast Du vielleicht noch drei Antworten für mich?

  • Kann man auf andere Art und Weise den Namen eines Projektes ändern?
  • Bei jedem "Run" muß man vorher auf Stop drücken. Läßt sich das einstellen, daß der Simulator sofort startet?
  • In verschiedenen Videos sehe ich, daß die Verknüpfungen gleich nach class .... erstellt werden und machmal nach override funk ... Hat das eine Bedeutung bzw. einen Grund?

 

Vielen Dank nochmals und
LG
Franz

 

Hast Du vielleicht noch drei Antworten für mich?

  • Kann man auf andere Art und Weise den Namen eines Projektes ändern?
  • Bei jedem "Run" muß man vorher auf Stop drücken. Läßt sich das einstellen, daß der Simulator sofort startet?
  • In verschiedenen Videos sehe ich, daß die Verknüpfungen gleich nach class .... erstellt werden und machmal nach override funk ... Hat das eine Bedeutung bzw. einen Grund?

1) https://stackoverflow.com/questions/33370175/how-do-i-completely-rename…

2) Wenn Du den Simulator nach dem Test einfach mit Command-Q beendest, musst Du nicht mehr "Stop" drücken .Wenn Du das vergisst, fragt Dich Xcode aber doch sobald Du "Run" drückst, ob Du stoppen willst, und Du kannst einfach mit Return bestätigen?!

3) Mit "Verknüpfungen" meinst Du IBOutlets und IBActions, oder? Outlets sind ja ganz "normale" properties von Klassen, und die werden nach Konvention als erstes in der Klassendefinition definiert (kein "Muss", aber bei Weitem das Sinnvollste!). IBActions sind wiederum einfach Funktionen, die werden theoretisch irgendwo in der Klassendefinition untergebracht. Dass Outlets oder Actions innerhalb einer Funktion angelegt werden (also nach "override func") ist mehr als merkwürdig...

Viele Grüße,

mabi

Ich möchte als Übungsstück eine App zur Berechnung der Fakultät erstellen. Das View läuft im Simulator nach dem Fehler nun wieder. Die Rekursion zur Berechnung habe ich mit playground geschrieben und getestet.

Nun wollte ich diese Methode in der App einfügen. Das Eingabefenster ist ja von Typ "text" = (TextField)  und die Funktion

func fakultaet(_ n: Int) -> Int {
...}

erfordert aber einen Wert von Typ "Integer". Meine Idee war

fakultaet(Int(eingabeFeld)).

Leider bekomme ich die Meldung
Initializer 'init(_:)' requires that 'UITextField' conform to 'BinaryInteger') als Zusatz (1. Where 'T' = 'UITextField' (Swift.SignedInteger).

Ich habe es auch mit einer Variablen versucht indem ich den Eingabewert in ein Integer umwandelte und der Variablen zuwies
var n = Int(eingabeFeld.text!)

Hier lautet die Meldung
Value of optional type 'Int?' must be unwrapped to a value of type 'Int'

Gibt es bei Funktionen gleich welcher Art andere Regeln als bei normalem Code? Ich habe schon ein anderes Programm geschrieben wo ich mit Textfeldern kein Problem hatte. Es waren halt keine Funktionen dabei.

Hast Du auch hier eine Idee?

Aber das sollte Xcode doch sogar alleine vorschlagen? Klick "fix" im Fehler an...

var n = Int(eingabeFeld.text!)!