czytanie stringa z pliku linia po linii do tablicy

0

Interesuje mnie ten temat: https://simpledevcode.wordpress.com/2015/01/03/convert-infix-to-reverse-polish-notation-c-implementation/ jednak nie rozumiem dlaczego program nie działa jeśli stringa podamy w takiej formie:

  string infix = "3^4+(11-(3*2))/2";

chce rozwiązać to zadanie w taki sposób aby notacje infiksową do konwersji podawać w pliku w następującej postaci:

1 // liczba wyrazen do konwersji
a+b+(~a-a) // wyrazenie do konwersji

Próbowałem robić to w taki sposób ale nic nie wyświetla:

int main() {

    vector<string> tokens;//store the tokens here
    ifstream in;
    openFile(in);
    int dataSets;

    in >> dataSets;
    for (int j = 0; j < dataSets; ++j) {
        string infix;
        istringstream iss(infix);
        while (getline(in, infix)) {

            while (iss) {
                string temp;
                iss >> temp;
                chars.push_back(temp);
            }


            vector<string> result;//output vector
            stack<string> stack;//main stack


            for (unsigned int i = 0; i < tokens.size(); i++)  
            {
            // funkcje
            }
        }
    }
    return 0;
}
1

Po kodzie nie widać po co Ci jawna liczba lini do wczytania w pliku, wydaje się całkowicie redundantna. Wywal ją, wczytaj wszystkie linie i będziesz wiedział ile masz wyrażeń.

ifstream in;
openFile(in);
std::vector<std::string> fileLines;
for(std::string line; std::getline(in, line);)
    fileLines.push_back(line);

std::cout << "Data sets: " << fileLines.size() << "\n";

A Twój kod nie daje rezultatów przez ten błędny fragment:

istringstream iss(infix);
        while (getline(in, infix)) {

            while (iss) {
                string temp;
                iss >> temp;
                chars.push_back(temp);
            }

Konstruując std::istringstream za pomocą std::string nie sprawiasz, że owy stream będzie obserwował zawartość std::string, następuje tu tylko kopiowanie zawartości przy konstrukcji, a że infix jest w tym momencie pusty, to w Twojej pętli while iss również będzie pusty.

0
several napisał(a):

Po kodzie nie widać po co Ci jawna liczba lini do wczytania w pliku, wydaje się całkowicie redundantna. Wywal ją, wczytaj wszystkie linie i będziesz wiedział ile masz wyrażeń.

ifstream in;
openFile(in);
std::vector<std::string> fileLines;
for(std::string line; std::getline(in, line);)
    fileLines.push_back(line);

std::cout << "Data sets: " << fileLines.size() << "\n";

A Twój kod nie daje rezultatów przez ten błędny fragment:

istringstream iss(infix);
        while (getline(in, infix)) {

            while (iss) {
                string temp;
                iss >> temp;
                chars.push_back(temp);
            }

Konstruując std::istringstream za pomocą std::string nie sprawiasz, że owy stream będzie obserwował zawartość std::string, następuje tu tylko kopiowanie zawartości przy konstrukcji, a że infix jest w tym momencie pusty, to w Twojej pętli while iss również będzie pusty.

Ok dzięki, nie mam zielonego pojęcia czym to zastąpić. Szukałem po różnych forach ale nie znalazłem odpowiedzi w zamieszczonych wcześniej pytaniach. Skoro infix pobieram z pliku to jak to zaimplementować aby poprawnie działało na zasadzie którą przedstawiłem? Pojawia się dodatkowy problem bo nie wiem dlaczego program nie działa jeśli podam stringa bez spacji

2

No ale co Ty chcesz zastępować, przecież dałem Ci gotowy kod, który wczyta Ci linia po lini i na pewno żadna spacja tutaj nie przeszkodzi - DOWÓD.

0
several napisał(a):

No ale co Ty chcesz zastępować, przecież dałem Ci gotowy kod, który wczyta Ci linia po lini i na pewno żadna spacja tutaj nie przeszkodzi - DOWÓD.

Dzięki, mój program teraz działa tak jak chciałem. Niestety nie dla kazdego wyrazenia otrzymuje poprawny wynik.

a+b+(~a-a) -> ab+a~a-+ // poprawny

np.
x=~~a+b*c -> x~a~bc*+= // niepoprawny mój
x=~~a+b*c -> xa~~bc*+= // poprawny

x=a^b^c -> xab^c^= // niepoprawny mój
x=a^b^c -> xabc^^= // poprawny

Obecny kod

bool isOperand(std::string ch) {

    return ch >= "a" && ch <= "z";
}

bool isOperator(std::string ch) {

    return ch == "=" || ch == "<" || ch == ">" || ch == "+" || ch == "-" || ch == "*" || ch == "/" || ch == "%" ||
           ch == "^" || ch == "~";
}

int priority(std::string ch) {

    if (ch == "~")
        return 5;
    if (ch == "^")
        return 4;
    if (ch == "*" || ch == "/" || ch == "%")
        return 3;
    if (ch == "+" || ch == "-")
        return 2;
    if (ch == "<" || ch == ">")
        return 1;
    if (ch == "=")
        return 0;
}

int main() {

    ifstream in;
    openFile(in);
    int dataSets;

    std::vector<std::string> fileLines;
    for (std::string line; std::getline(in, line);)
        fileLines.push_back(line);

    dataSets = stoi(fileLines[0]);

    for (int j = 1; j < dataSets + 1; ++j) {

        string infix = fileLines[j];
        vector<string> result;//output vector
        stack<string> stack;//main stack


        for (size_t i = 0; i < infix.length(); i++)  //read from right to left
        {
            char c = infix[i];
            string temp(1,c);

            if (isOperand(temp))
                result.push_back(temp);
            if (temp == "(") {
                stack.push(temp);
            }
            if (temp == ")") {
                while (!stack.empty() && stack.top() != "(") {
                    result.push_back(stack.top());
                    stack.pop();
                }
                stack.pop();
            }
            if (isOperator(temp)) {
                while (!stack.empty() && priority(stack.top()) >= priority(temp)) {
                    result.push_back(stack.top());
                    stack.pop();
                }
                stack.push(temp);
            }
        }
        //pop any remaining operators from the stack and insert to outputlist
        while (!stack.empty()) {
            result.push_back(stack.top());
            stack.pop();
        }

        for (int i = 0; i < result.size(); i++) {
            cout << result[i];
        }
        cout<<endl;

    }
    return 0;
}

Staram się znaleźć błąd.

0

Popraw warunek na:

while (!stack.empty() && priority(stack.top()) > priority(temp)) 
0

Sama pętla wygląda OK, oczywiście Zdebuguj porządnie; ale Powinieneś mieć jeszcze priority nawiasu lewego, o jeden niższe niż + i -.

@_0x666_

0x666 napisał(a):

Popraw warunek na:

while (!stack.empty() && priority(stack.top()) > priority(temp)) 

Czemu nierównośc silna? Tutaj też mają słabą: https://runestone.academy/runestone/books/published/pythonds/BasicDS/InfixPrefixandPostfixExpressions.html#general-infix-to-postfix-conversion

0

@lion137: opierałem się na oczekiwaniach OP - chce, by operacje o tych samych priorytetach były robione od prawej, stąd taki warunek.

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