Mathematische Funktion einlesen



  • Hallo zusammen,

    ich habe mir ein kleines Programm gebastelt, welches mit mehreren Verfahren die Nullstellen einer Funktion finden kann, wobei es keine Rolle spielt, ob es sich dabei um ein Polynom handelt, um eine gebrochen rationale Funktion oder irgendetwas anderes.
    Das Problem ist aber: Ich kann bis jetzt immer nur die Nullstellen einer Funktion suchen lassen, die ich vor dem kompilieren in den Code geschrieben habe. Also z.B.:

    double f(const double& x)
    {
           return .2 * pow(x+2,2) - .1;
    }
    

    Nun würde ich gerne das Programm erweitern, so dass der Benutzer die Funktion eingeben kann, etwa so:

    Bitte geben Sie die Funktion ein:
    f(x) = x^2 + sin(x) - 8
    ...
    

    Hat jemand eine Idee, wie sich so etwas einigermaßen leicht umsetzen lässt? Mir fehlt nur die Idee, ich erwarte keinen fertigen Code...

    Vielen Dank schonmal 😉



  • kannst den string z.b in ne baumstruktur klatschen, bei der jeder knoten einen operator darstellt und die tatsächlichen zahlen in den blättern landen. dazu legst du dir eine operatorreihenfolge fest, die den string sukkzessive splittet.

    1+2*3 (operatorreihenfolge *, +)
    
    erster split:
    
    '+'
     +- 1
     +- 2*3
    
    zweiter split
    
    '+'
     +- 1
     +- '*'
         +- 2
         +- 3
    
    jetzt kannst du dich von unten nach oben durch den baum hangeln und die knoten auflösen.
    
    '+'
     +- 1
     +- 6
    
    '7'
    

    die operatorreihenfolge splittet "rückwärts", was beim rückwärtigen abarbeiten dann für die "richtige" reihenfolge sorgt.



  • Nimm dafür LUA.



  • Nimm dafür Python, ist für diesen Zweck IMHO noch besser geeignet als lua. Ist aber Geschmackssache.

    MfG Kimmi



  • Ja, vielen Dank schonmal.
    @thordk: So muss man es wohl machen, wenn man es rein in C++ implementieren will.

    Hat einer von Euch zufällig einen guten Link herumfliegen, wo erklärt wird, wie man eine Skriptsprache in C++ einbindet? Das hab ich noch nie gemacht. Ich könnte dann ja auch aus dem String den Skript-code generieren und dann das skript aufrufen, oder? Dann müsste ich nur ein paar Syntaxkorrekturen machen und den String dann als Funktion in das Skript-File schreiben.



  • Also Lua ist am einfachsten einzubinden, weil die Scriptsprache auch "einfacher" ist (was nicht heißt, das sie nicht gut ist!). Ich würde an deiner Stelle dem User, der die Formel eingibt, sagen, das er sich an Lua-Konventionen halten soll. Denn im Prinzip ist Lua recht einfach zu lernen (ist für Ingenieure und nicht Programmierer erfunden!). Die Formel gibt man auch nicht viel anders an als du es vorgemacht hast. Das würde ungefähr so aussehen:

    pow(x,2) + sin(x) - 8
    

    Bin jetzt nicht so Lua-bewandert, aber so würde der User es eingeben und du kannst es 1:1 durch den Lua-parser jagen. Fertig.

    Hier ist ein sehr gutes Tutorial wie man Lua in sein Programm einbindet.

    Ein User der nur die Math-Funktionen benötigt, kannst du auf diese Referenz verweisen. Vielleicht noch selber ein zwei Tips und Erklärungen machen, damit ein normaler User einen einfachen Einstieg hat. Fertig.



  • Vielen Dank, das ist Spitze!
    C++ lernen macht mir doch jeden Tag mehr Spaß. Schade, dass ich eigentlich ganz andere Sachen lernen müsste :p
    Damit komme ich auf jedenfall weiter...



  • iiiih, scriptsprachen. weiche, satan!



  • WarMal schrieb:

    Das Problem ist aber: Ich kann bis jetzt immer nur die Nullstellen einer
    Funktion suchen lassen, die ich vor dem kompilieren in den Code
    geschrieben habe.

    Hallo !
    Während der Syntaxanalyse zerlegt der Compiler deine Funktion, also
    deinen arithmetischen Ausdruck in einzelne Elemente( Funktionen, Operatoren,
    Konstanten, Zahlenwerte)
    und wandelt ihn in die sogenannte Postfixnotation, auch UPN (Umgekehrte
    Polnische Notation) genannt, um.

    In dieser Form enthält der Ausdruck keine Klammern mehr und liegt
    nun also in Elemente zerlegt in Form eines Stack vor.
    Es ist also ein Stapel. Das hat gegenüber einer Baumstruktur insofern
    den Vorteil, als das die Elemente nacheinander vom Stapel geholt und
    berechnet werden, es muss nicht in einem Baum iteriert werden.

    Hier ist son Verrückter, der das als ein C-Modul programmiert hat:
    http://www.c-plusplus.net/forum/profile-var-mode-is-viewprofile-and-u-is-104825.html
    Das ist so gemacht, das es auch in C++ eingebunden werden kann. Fertig.
    Für Eingaben, die hin- und wieder mal entgegengenommen werden geeignet,
    für Nullstellenberechnungen so wie du sie vorhast, könnte es allerdings
    noch optimiert werden. ( Je nachdem, ob es schnell genug für deine Zwecke ist )

    MfG
    🙂



  • IstNoch schrieb:

    Hallo !
    ...
    MfG
    🙂

    👍 Der Text hätte von mir sein können 😃
    🙂

    Aber..

    IstNoch schrieb:

    Hier ist son Verrückter, der das als ein C-Modul programmiert hat: ...

    äähöm..hüstel... wie bitte ? 😕

    😉 😃 🕶



  • ich hab die stackvariante vor ca. 15 jahren in ucsd pascal implementiert, bin ich cool oder was? :p

    find die baumvariante intuitiver und einfacher nachzuvollziehen. die stackvariante ist allerdings üblicher, das stimmt.



  • thordk schrieb:

    ich hab die stackvariante vor ca. 15 jahren in ucsd pascal implementiert, bin ich cool oder was? :p

    👍 Ja, definitiv 👍

    🙂


Anmelden zum Antworten