Przerobienie kodu.

0

Witam, czy mógłby ktoś mi pomóc w przerobieniu tego kodu na taki, by wyrażenie const char * expressionToParse = "6.5-2.5*10/5+2*5"; nie było zdefiniowanie globalnie, tylko by była możliwość podania wyrażenia z klawiatury? Męczę się, próbuje przeróżnymi funkcjami, ale nic nie idzie ;v


#include <iostream>
#include <sstream>

using namespace std;

const char * expressionToParse = "6.5-2.5*10/5+2*5";

istringstream parse(expressionToParse) ;

char peek()
{
    return static_cast<char>(parse.peek()) ;
}

char get()
{
    return static_cast<char>(parse.get()) ;                    
}

double expression();

double number()
{
    double result ;
    parse >> result ;                      
    return result;
}

double factor()
{
    if ((peek() >= '0' && peek() <= '9') || peek() == '.')
        return number();
    else if (peek() == '(')
    {
        get(); // '('
        double result = expression();
        get(); // ')'
        return result;
    }
    else if (peek() == '-')
    {
        get();
        return -expression();
    }
    return 0; // error
}

double term()
{
    double result = factor();
    while (peek() == '*' || peek() == '/')
        if (get() == '*')
            result *= factor();
        else
            result /= factor();
    return result;
}

double expression()
{
    double result = term();
    while (peek() == '+' || peek() == '-')
        if (get() == '+')
            result += term();
        else
            result -= term();
    return result;
}

int main(double argc, char* argv[])
{

    double result = expression();
    cout << result << endl;
    return 0;
}
1

Po co męczyć się z const char* gdy wymyślono std::string?

1

Cały ten program jest tak, "zdizajnowany", że istnieje to globalne expressionToParse podawane sobie potem przez funkcje. Zmień to, niech funkcje biorą stringa jako parametr, obraiają go i zwracają, wtedy nie będą potrzebne globalne definicje.

0

Cały ten program jest tak, "zdizajnowany", że istnieje to globalne expressionToParse podawane sobie potem przez funkcje. Zmień to, niech funkcje biorą stringa jako parametr, obraiają go i zwracają, wtedy nie będą potrzebne globalne definicje.

Sęk w tym że nie wiem jak to zrobić, próbuje próbuje tylko wciąż errory etc. Mógłbyś Ty, lub ktokolwiek inny pokazać to na przykładzie?..

0

O kurde, znasz prawa matematyczne?

Podajesz taki wzór gdzie wszystkie prawa się mieszają, wszyscy informatycy żeby się nie pogubić dodawają nawiasy, i kurde to jest coś super.
całe życie męczysz się z obliczeniami mjak wystarczy tylko spojrzeć na wynik.
}Dobra nie wime co piszę i nie ma msił poprawiaćwszzytstkiego.

prostytutka wyglda to loigicznie.

nie nkurwau teraz to dobrze napidszę

jak to możliwe, kur,wa dlaczego źle poiszę//////////////////////

0
Merylin napisał(a):

Cały ten program jest tak, "zdizajnowany", że istnieje to globalne expressionToParse podawane sobie potem przez funkcje. Zmień to, niech funkcje biorą stringa jako parametr, obraiają go i zwracają, wtedy nie będą potrzebne globalne definicje.

Sęk w tym że nie wiem jak to zrobić, próbuje próbuje tylko wciąż errory etc. Mógłbyś Ty, lub ktokolwiek inny pokazać to na przykładzie?..

Poszukaj Algorytmu Dijkstry, który ewaluuje wyrażenia poprawnie znawiasowane, używając stosu, (dwóch stosów)

1

Nie popatrzylem, Ty masz wyrazenie bez nawiasow, pozniej cos napisze.

0

Wspominana juz Odwrotna Notacja Polska pomoże, a stokenizować wyrażenie arytmetyczne jest w miarę łatwo przy użyciu metod na stringach: replace i split:

fun tokenize(input_str):
    input_str = input_str.replace("+", " + ").replace("-", " - ").replace( "*", " * ").replace("/", " / ")
    input_str = input_str.replace("(", " ( ").replace(")", " ) ")
    return input_str

Czyli otaczamy operatory i nawiasy spacjami, więc to co zostanie to będą operandy.

Potem konwersja do ONP:

  1. String wejściowy konwertujemy do listy - split
  2. Tworzymy stos na operatory i listę zwracającą wynik.
  3. Iterujemy po liście i:
    • jeśli token jest operandem (tu można uzyć, np regexu do rozpoznawania typu liczb, na jakich działa kalkulator) to dołączamy na koniec listy wynikowej (append);
    • jeśli jest lewym nawiasem wrzucamy na stos;
    • jeśli jest prawym nawiasem, to usuwamy elementy ze stosu, aż zostanie usunięty odpowiadający mu nawias lewy, przy okazji operatory dokładamy na koniec listy zwracanej;
    • jeśli token to operator, to wrzucamy go na stos, wcześniej ściągajac i dodając do listy wynikowej wszystkie operatory o takim samym lub wyższym priorytecie.
      Po skończeniu iteracji, jeśli jakieś operatory jeszcze są na stosie dodajemy na koniec listy wynikowej.

Ewaluacja ONP:

  1. Jeśli na wejściu jest string, to konwertujemy do listy (split).
  2. Tworzymy pusty stos.
  3. Iterujemy po liście i:
    • jeśli token to operand konwertujemy do odpowiedniego typu i wrzucamy na stos;
    • jeśli operator to dwa razy zrzucamy ze stosu, pierwszy pop(), to drugi operand, a drugi to pierwszy, wykonujemy operację arytmetyczną i dajemy z powrotem na stos.
  4. Po skonczeniu iteracji resultat jest na stosie, zwracamy więc pop().

Przykładowy kod, odwzorowujący, dokładnie te algorytmy, (Tokenizer, ParseExpression, Eval) tutaj: https://github.com/lion137/Java-Numeric-Calculator .
String split w C++: https://stackoverflow.com/a/236976

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