Pomysł na elementarne wyrażenie, podczas tokenizacji wzoru matematycznego

0

Dzień dobry.

Poszukuję pomysłu na elementarne wyrażenie (Symbol), które będę mógł łączyć operatorami +,-,*,/,^

Pomysł mam na razie taki, aczkolwiek jest niedoskonały

var Symbol = function (mLicznik, mMianownik, zmienna, pLicznik, pMianownik) {
    this.mnoznik = new Ulamek(mLicznik, mMianownik);
    this.zmienna = new Zmienna(zmienna);
    this.potega = new Ulamek(pLicznik, pMianownik);
    
    this.zapis = function () {
        var zap = "";
        //zap += this.znak;
        zap += (this.mnoznik.zapis() === Blad) ? "" : this.mnoznik.zapis();
        zap += this.zmienna.zapis();
        zap += (this.potega.zapis() === Blad) ? "" : "^" + this.potega.zapis();
        
        return zap;
    };
};

jednak to rozwiązanie ma wiele wad. np, brak wielokrotnych ułamków 1/2/2, albo fakt, że ułamki mogą być tylko liczbami i nie przejdzie takie coś: 2/x/y etc.

Jaką proponujecie symbolikę Symbolu?

Dzięki
M.


Zmodyfikowałem konstruktor Ułamka, tak, że teraz może zawierać inne ułamki, włącznie ze stałymi tekstowymi:

var Ulamek = function (num1, num2) {
    this.typ = "";
    
    if (num1 instanceof Ulamek || num2 instanceof Ulamek)
        this.typ = UlamekWUlamku;
    else if (czyLiczbaLubStr(num1) && czyLiczbaLubStr(num2))
        this.typ = UlamekZwykly;
    else if (czyLiczbaLubStr(num1) && !czyLiczbaLubStr(num2))
        this.typ = UlamekDziesietny;
    else
        this.typ = Blad;
    
    this.licznik = (this.typ !== Blad ? num1 : 0);
    this.mianownik = (this.typ === UlamekDziesietny ? 1 : num2);
    
    if (this.typ === UlamekZwykly) {
        this.licznik = Math.abs(this.licznik) * Math.sign(this.licznik * this.mianownik);
        this.mianownik = Math.abs(this.mianownik);
    }
    
    this.dziesietnie = (typeof num1 === 'number' && typeof num2 === 'number') ? this.licznik / this.mianownik : num1;
    
    this.toString = function () {
        return this.licznik.toString() + "/" + this.mianownik.toString();
    };
    
    this.zapis = function () {
        return (this.typ !== Blad) ? (this.typ === UlamekDziesietny ? String(this.dziesietnie) : this.toString()) : Blad;
    };
};

Teraz muszę jeszcze resztę ogarnąć :)

1

@mpaw:

Jaką proponujecie symbolikę Symbolu?

Proponuję opisać, co właściwie chcesz zrobić, co robi ta twoja funkcja i czego jej brakuje.

0

@Freja Draco:

Chcę dokonać tokenizacji wzoru matematycznego, zapisanego w formie wyrażenia w języku programowania, np. 2/x^2+4*x^6+3. Funkcję szatkującą i wykonującą tokenizacji na poziomie stringów, mam już napisaną (z pomocą GitHuba :D ). Teraz potrzebuję opakować te tokeny w Symbole, żebym mógł nimi łatwo gospodarzyć. :)

0

@lion137:

Dzięki, ale mnie rozchodzi się o tokenizację wzoru matematycznego, a nie pisanie kompilatora. Działania to: + - * / ^ () That's all.

0

Tam MAsz właśnie opisaną klasę Token, możesz ją zawęzić do potrzeb tokenizacji wzorów.

0

@lion137:

Dziękuję. Są w sieci gotowe biblioteki w JS do takich rzeczy, ale wszystkie one mają pewne wady, które determinują chęć korzystania z nich przeze mnie. Jedna z nich, jest na tyle duża, że pomimo szczerych chęci i aktów heroizmu, poprawiłem wiele błędów, ale nadal są jeszcze inne błędy i niejednoznaczności, nie mam już zdrowia babrać się w 10k+ linii kodu i wyszukiwać gdzie leży przyczyna. Dlatego postanowiłem napisać własną, o wiele mniejszą libkę, tylko z funkcjami które mnie interesują, jednak będąc świadomym, co gdzie leży i jak działa.

Dzięki
M.

0

Oczywiście, ale idę o zakład, że nic zasadniczo różnego od podlinkowanej klasy Token nie wymóżdżysz :)

0

@lion137:

Ta libka np. http://algebrite.org/ potrafi policzyć 50000!. Co prawda, robi to na moim i5 przez 20 sek. ale daje radę. Wynik na 20 stron :D . Ale mi nie zależy na samym liczeniu, tylko na tokenizacji i akceptowalnym przeze mnie wyświetlaniu.

0

Jednak odgrzebuję temat. Podany link @lion137 jest nie do końca użyteczny. Ja nie chcę obliczać ostatecznej wartości, tylko przekształcać równania, dodawać/odejmować/dzielić/mnożyć niewiadome etc.

Np:
x+x+x*2-3.5x ma mi zamienić na 1/2*x etc. Albo 2x+3^2+x^2+3x^2 ma zamienić na 2x+9+4x^2. Jaka struktura klasy symbolu będzie najwłaściwsza i gdzie szukać odpowiedzi?

Dzięki
M.

PS.
Dla ścisłości, pokażę co mam.
http://www.wklejto.pl/869512

0

Dzięki. Czyli jednak trzeba to zrobić w ONP (RPN). Znalazłem fragment w jednej z libek:

this.parse = function (e, substitutions) {
    e = prepare_expression(e);
    substitutions = substitutions || {};
    //three passes but easier to debug
    var tokens = this.tokenize(e);
    var rpn = this.toRPN(tokens);
    return this.parseRPN(rpn, substitutions);
};

Faktycznie, używa RPN, dzięki :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1