Странно работает цикл

156
07 мая 2019, 11:10

Есть код калькулятора ,вот он :

#include "pch.h"
#include <iostream>
#include <string>
#include <strstream>
#include <vector>
using namespace std;
vector <char> arr;
vector<double> values;
int counter =0;
class Token {
    public:
    char tok = NULL;
    double num = NULL;
    Token() {
    }
    Token(double a) {
        num = a;
    }
    Token(char c) {
        tok = c;
    }
    Token(char c1, double n) {
        tok = c1;
        num = n;
    }
};
Token get_token(char q) 
{
    switch (q)
    {
    case 10:
    {
        if (arr.empty() == false) {
            cin.putback(' ');
            for (int i = arr.size(); i > 0; i--) {
                int a = i;
                a--;
                cin.putback(arr[a]);
            }
            arr.clear();
            double num1;
            cin >> num1;
            char qqq;
            cin.get(qqq);
            Token new1 = Token(num1);
            return new1;
        }
    }
    case '(':
    case ')':
    case '*':
    case '/':
    case '+':
    case '-': {
        if (arr.empty() == false) {
            cin.putback(' ');
            for (int i = arr.size(); i > 0; i--) {
                int a = i;
                a--;
                cin.putback(arr[a]);
            }
            arr.clear();
            double num1;
            cin >> num1;
            char qp;
            cin.get(qp);
            Token new2 = Token(q, num1);
            return new2;
        }
        Token new3 = Token(q);
        return new3;
    }
    default:
        break;
    }

}
vector <Token> tokens;
void create_fun() {
    Token q, t,p;
    char ch;
    int i = 1;
    bool stop = false;
    while (stop == false) {
        cin.get(ch);
        switch (ch) {
        case'0':
        case'1':
        case'2':
        case'3':
        case'4':
        case'5':
        case'6':
        case'7':
        case'8':
        case'9': {
            arr.push_back(ch);
            break; }
        case 10:
        {
                q = get_token(10);
                tokens.push_back(q);
            stop = true;
            break; }
        case '.':
        {
            arr.push_back('.');
            break;
        }
        default:
            t = get_token(ch);
            tokens.push_back(t);
            break;
        }
    }
}
double term(int a,int b) 
{
    double val = tokens[a].num;
    for (int i = a; i < b; i++) {
        if (tokens[i].tok == '*') {
            val *= tokens[i + 1].num;
        }
        if (tokens[i].tok == '/') {
            val /= tokens[i + 1].num;
        }
        if (tokens[i].tok == '+' || tokens[i].tok == '-') {
            counter = i - 1;
            return val;
        }
        counter = i+1;
    }
    return val;
}
double expression(int a, int b,double c)
{
    double val = c;
    for (int i = a; i < b; i++) {
        if (tokens[i].tok == '-') {
            if (tokens[i + 1].tok == '+' || tokens[i + 1].tok == '-' || tokens[i + 1].tok == NULL || tokens[i + 1].tok == ')' || tokens[i+1].tok == 10) {
                val -= tokens[i + 1].num;
            }
            else {
                val -= term(i + 1, b);
                i = counter;
            }
        }
        else if (tokens[i].tok == '+') {
            if (tokens[i + 1].tok == '+' || tokens[i + 1].tok == '-' || tokens[i + 1].tok == NULL || tokens[i + 1].tok == ')') {
                val += tokens[i + 1].num;
            }
            else {
                val += term(i + 1, b);
                i = counter;
            }
        }
        else if (tokens[i].tok == NULL)
        {
            val = val;
        }
        else if (tokens[i].tok == '*'|| tokens[i].tok == '/')
        {
            val = term(i, b);
            i = counter;
        }
        else if (tokens[i].tok == ')') {
            counter = i;
            return val;
        }
    }
    return val;
}
void initial_expression()
{
    double result = 0;
    int p = tokens.size();
    int start=-1,end ;
    for (int i = counter; i < tokens.size(); i++) {
        if (tokens[i].tok == '(') {
            start = i;
            for (int q = counter; q < tokens.size(); q++) {
                cout << "TOKEN SIZE : " << tokens.size() << endl;
                cout << "q on the start is: " << q << endl;
                for (Token x : tokens) {
                    cout << x.num << x.tok;
                }
                if (tokens[q].tok == ')') {
                    end = q;
                    if (start == 0) {
                        result = expression(1, end, tokens[start + 1].num);
                        if (end != tokens.size() - 1) {
                            tokens[end + 1].num = result;
                            tokens[end].tok = NULL;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end + 1);
                            q = tokens.size();
                        }
                        else
                        {
                            tokens[end].num = result;
                            tokens[end].tok = NULL;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end);
                            q = tokens.size();
                        }
                    }
                    else
                    {
                        result = expression(start, end, tokens[start + 1].num);
                        if (end != tokens.size() - 1) {
                            tokens[end + 1].num = result;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end + 1);
                            q = tokens.size();
                        }
                        else
                        {
                            tokens[end].num = result;
                            tokens[end].tok = NULL;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end);
                            q = tokens.size();
                        }
                    }
                    cout << "q at the end is: " << q << endl;
                    for (Token x : tokens) {
                        cout << x.num << x.tok;
                    }
                }
            }
        }
    }
    if (start == -1) {
        result = expression(0, tokens.size(),tokens[0].num);
    }
    if (tokens.size() < p) {
        result = expression(0, tokens.size(), tokens[0].num);
    }
    cout << "THE RESULT IS: " << result << endl;
}

int main()
{
    create_fun();
    initial_expression();   
    system("pause >> NUL");
    return 0;
}

Он делит выражение на токены с числом и знаком ,к примеру 1-2 будет разделено на 1- 210 (10 т.к. вводится enter) ,есть метод initial_expression который в выражении ищет скобки ,потом их содержимое вычисляет с помощи метода expression и удаляет все токены в скобках вместе со скобками и на их место ставит результат вычисления этих скобок, тоесть к примеру у нас есть (2+3)-1 то в результате получится 5-1 ,потом если скобки закончились он опять вычисляет выражение уже без скобок,так у меня вопрос : в методе initial_expression есть цикл (int q = counter; q < tokens.size(); q++) ,так внутри этого цикла q присваивается значение tokens.size(); но почему то q всеравно продолжает быть таким же как и прежде,к примеру если ввести (2*3)-(2*3) то tokens.size() будет равен 8 после того как эта часть кода обрезает вектор то tokens.size() становится равно 5 ,потом q = tokens.size() = 5 , но почему то это q = 5 куда-то девается и q просто продолжает с того числа на котором остановилось,но без этого q = tokens.size() код работает не правильно.

Вот цикл о котором идет речь :

for (int q = counter; q < tokens.size(); q++) {
                if (tokens[q].tok == ')') {
                    cout << "q on the start is: " << q << endl;
                    for (Token x : tokens) {
                        cout << x.num << x.tok;
                    }
                    end = q;
                    if (start == 0) {
                        result = expression(1, end, tokens[start + 1].num);
                        if (end != tokens.size() - 1) {
                            tokens[end + 1].num = result;
                            tokens[end].tok = NULL;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end + 1);
                            q = tokens.size();
                        }
                        else
                        {
                            tokens[end].num = result;
                            tokens[end].tok = NULL;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end);
                            q = tokens.size();
                        }
                    }
                    else
                    {
                        result = expression(start, end, tokens[start + 1].num);
                        if (end != tokens.size() - 1) {
                            tokens[end + 1].num = result;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end + 1);
                            q = tokens.size();
                        }
                        else
                        {
                            tokens[end].num = result;
                            tokens[end].tok = NULL;
                            tokens.erase(tokens.begin() + start, tokens.begin() + end);
                            q = tokens.size();
                        }
                    }
                    cout << "q at the end is: " << q << endl;
                    for (Token x : tokens) {
                        cout << x.num << x.tok;
                    }
                }
            }

А вот то что он выводит если ввести в консоль (2*3)-(2*4):

      (2*3)-(2*4)
 q on the start is: 2
      0(2*3)0-0(2*4)0
      q at the end is: 5
       6-0(2*4)0
      q on the start is: 3
      6-0(2*4)0
     q at the end is: 2
    6-8
  THE RESULT IS: -2
READ ALSO
Структура данных для хранения callbackов

Структура данных для хранения callbackов

Мне нужна структура данных, которая каждой строке будет ставить в соответствие некоторую callback-функциюЭта структура будет инициализироваться...

139
Можно ли как-то ещё ускорить данный код?

Можно ли как-то ещё ускорить данный код?

Где subset1 и subset2 - это вектора подмножеств первой и второй половины множества соответственно

134
Как работает этот код по распаковке TGA файла? (unload_rle_data)

Как работает этот код по распаковке TGA файла? (unload_rle_data)

Начал копать библиотеку уроков по тому как работает OpenGL и не могу разобраться с одним методомСсылка на курс: https://github

131
Доступ к элементам std::map по индексу

Доступ к элементам std::map по индексу

Интересует, как можно получить доступ к элементу map'ы с индексом iНо! К примеру, при перебирании map'ы при помощи итерататора она отсортирована...

154