Как в С++ выполняется сложение строк? В чем пробела моего кода? Вот его фрагмент:
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 << "\n";
}
}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;
}
Answers & Comments
std::to_string(Calculation())