• Как в С++ выполняется сложение строк? В чем пробела моего кода? Вот его фрагмент:
    int Claculation() {...}

    s = "2+2";
    s += "=" + Calculation(); //В итоге получается, что s = "2+2pause", хотя Calculation возвращает 4.


    Полный код:


    #include<iostream>
    #include<string>
    #include<cstring>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<map>
    #include<set>using namespace std;int Factorial(int a)
    {
     return a == 0 ? 1 : Factorial(a - 1) * a;
    }bool ExcessBrackets(string s) //Исправить так, чтобы удаление лишних скобок происходило за 1 цикл
    {
     int inBrackets = 0;
     bool end = false;
     for (int i = 1; i < s.length() - 1; i++)
     {
      inBrackets += s[i] == '(' ? 1 : s[i] == ')' ? -1 : 0;
      if (inBrackets < 0)
       end = true;
     }
     return inBrackets == 0 && !end && s.length() > 0 && s[0] == '(' && s[s.length() - 1] == ')';
    }vector<string> Parsing(string s)
    {
     vector<string> parse;
     int inBrackets = 0;
     string s1 = "";
     for (int i = 0; i < s.length(); i++)
     {
      if (s[i] == '(')
       inBrackets++;
      if (s[i] == ')')
       inBrackets--;
      if (inBrackets > 0 || s[i] != '+' && s[i] != '*' && s[i] != '-' && s[i] != '/')
       s1.push_back(s[i]);
      else
      {
       parse.push_back(s1);
       parse.push_back(string(1, s[i]));
       s1 = "";
      }
     }
     parse.push_back(s1);
     return parse;
    }int Calculation(string s); //Нужно для рекурсивного вызова Calculation -> Framework -> Calculation. Как исправить?int Framework(string s)
    {
     if (toupper(s[0]) == 'C')
     {
      int inBrackets = 0; //Надо ли здесь проверять скобки?
      string n = "", k = "";
      for (int i = 2; i < s.size(); i++)
       if (s[i] == ',' && inBrackets == 0)
       {
        n = s.substr(2, i - 2);
        k = s.substr(i + 1, s.size() - i - 2);
        break;
       }
       else
        inBrackets += s[i] == '(' ? 1 : s[i] == ')' ? -1 : 0;
      return Factorial(Calculation(n)) / Factorial(Calculation(k)) / Factorial(Calculation(n + "-" + k));
     }
     if (all_of(s.begin(), s.end(), ::isdigit))
      return stoi(s);
     cout << "Error";
     exit(0);
    }int Calculation(string s)
    {
     while (ExcessBrackets(s)) //Удаление лишних внешних скобок: (s) => s. Необходимо для Parsing
      s = s.substr(1, s.length() - 2);
     vector<string> parse = Parsing(s);
     int firstm = -1; //Нужна в следующем цикле для случая (a * b) * c => ((a * b) * c) (запомнает положение самой левой скобки в ряде произведений и делений)
     for (int i = 1; i < parse.size(); i += 2) //Расстановка скобок для операций * и /, идущих подряд, чтобы правильно взять производную типа: a * b * c => (a * b) * c
      if (parse[i] == "*" || parse[i] == "/") //Учесть, что может быть унарный символ
      {
       if (firstm == -1)
        firstm = i - 1;
       parse[i + 1] += ")";
       parse[firstm] = "(" + parse[firstm];
      }
     s = "";
     for (int i = 0; i < parse.size(); i++)
      s += parse[i];
     while (ExcessBrackets(s)) //Если были только умножения
      s = s.substr(1, s.length() - 2);
     parse = Parsing(s);
     if (parse.size() == 1)
      return Framework(parse[0]);
     if (parse[0] == "-" || parse[0] == "+")
      parse.insert(parse.begin(), "0");
     int rez = Calculation(parse[0]);
     for (int i = 0; i < parse.size() - 1; i += 2) //Проверить два подряд идущих знака
      if (parse[i + 1] == "-")
       rez -= Calculation(parse[i + 2]);
      else if (parse[i + 1] == "+")
       rez += Calculation(parse[i + 2]);
      else if (parse[i + 1] == "*")
       rez *= Calculation(parse[i + 2]);
      else if (parse[i + 1] == "/")
      {
       int divider = Calculation(parse[i + 2]);
       if (divider == 0) //Проверка на деления на ноль
       {
        cout << "Error";
        exit(0);
       }
       rez /= divider;
      }
      else //Если после числа идет не знак
      {
       cout << "Error";
       exit(0);
      }
     return rez;
    }void Print(string s)
    {
     map<char, vector<string>> symbols = { { '1',{ "#",
      "#",
      "#",
      "#",
      "#" } },  { '2',{ "###",
      "  #",
      "###",
      "#  ",
      "###" } },  { '3',{ "###",
      "  #",
      "###",
      "  #",
      "###" } },  { '4',{ "# #",
      "# #",
      "###",
      "  #",
      "  #" } },  { '5',{ "###",
      "#  ",
      "###",
      "  #",
      "###" } },  { '6',{ "###",
      "#  ",
      "###",
      "# #",
      "###" } },
      { '7',{ "###",
      "# #",
      "  #",
      "  #",
      "  #" } },  { '8',{ "###",
      "# #",
      "###",
      "# #",
      "###" } },  { '9',{ "###",
      "# #",
      "###",
      "  #",
      "###" } },  { '0',{ "###",
      "# #",
      "# #",
      "# #",
      "###" } },  { '+',{ "   ",
      " # ",
      "###",
      " # ",
      "   " } },  { '-',{ "   ",
      "   ",
      "###",
      "   ",
      "   " } },  { '*',{ " ",
      " ",
      "#",
      " ",
      " " } },  { '/',{ "   ",
      "  #",
      " # ",
      "#  ",
      "   " } },  { '(',{ " #",
      "# ",
      "# ",
      "# ",
      " #" } },  { ')',{ "# ",
      " #",
      " #",
      " #",
      "# " } },  { '=',{ "   ",
      "###",
      "   ",
      "###",
      "   " } } };
     for (int i = 0; i < 5; i++)
     {
      for (int j = 0; j < s.length(); j++)
       if (s[j] != ' ')
        cout << symbols[s[j]][i] << "  ";
      cout << "";
     }
    }int main()
    {
     string s, s1;
     getline(cin, s1);
     for (int i = 0; i < s1.length(); i++) //Удаляю пробелы
      if (s1[i] != ' ')
       s += s1[i];
     //Проверить на баланс скобок
     s += "=" + Calculation(s);
     Print(s);
     system("pause");
     return 0;
    }

Ответы 0

  • Добавить свой ответ

Войти через Google

или

Забыли пароль?

У меня нет аккаунта, я хочу Зарегистрироваться

How much to ban the user?
1 hour 1 day 100 years