Предназначен для выполнения простых вычислений, использующих основные арифметические действия и скобки. Выражение должно быть сохранено в файле “example.txt” в папке программы.
Пример: – 45.5 + 12 * ( -185 – 18 * (6 – 3 )) -217.5
Основная задача программы – обучение приемам работы с контейнером vector и функциями стандартной библиотеки.
Рассмотрим алгоритм программы. На вход программы передается строка текста (std::string) содержащая математическое выражение. Это текст, вычислять пока нечего.
Основные блоки программы:
- Рекурсивная функция разбора скобок func(). Нам неизвестна глубина вложенности скобок, по этому будем использовать рекурсию.
- Функция вычисления выражения в скобках parser, с учетом приоритетов выполняемых операций. Умножение и деление выполняются до сложения и вычитания.
// pract_vector.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using std::cout;
using std::endl;
//*******************************************
void arOut(std::vector<char> ar) {
for (char c : ar) {
cout << c;
}
}
//*******************************************
void arOut(std::vector<float> ar) {
for (float n : ar) {
cout << n << endl;
}
cout << endl;
}
//*********************************************
float matem(float a, float b, char d) {
float res{};
switch (d) {
case '+':res = a + b; break;
case '-':res = a - b; break;
case '*':res = a * b; break;
case '/':res = a / b; break;
default: {
std::cout << endl << "Ошибка в данных.";
exit(1);
}
}
return res;
}
//*********************************************
std::string calk(std::vector<float> arF, std::vector<char> d) {
std::string str{};
float res{};
int sdv{};
while (d.size() > 1) {
if ((d[0] == '*' || d[0] == '/') || (d[1] == '+' || d[1] == '-')) sdv = 0;
else sdv = 1;
res = matem(arF[sdv], arF[sdv + 1], d[sdv]);
arF.erase(arF.begin() + sdv);
arF[sdv] = res;
d.erase(d.begin() + sdv);
}
res = matem(arF[0], arF[1], d[0]);
return std::to_string(res);
}
//*********************************************
std::string parser(std::vector<char> ar) {
std::string str{};
std::vector<float> arF{};
std::vector<char> deystv{};
bool digit = true;
int arSize = ar.size();
bool first = true;
for (int i{}; i < arSize; ++i) {
if (ar[i] == ' ')continue;
if (digit) {
if ((ar[i] >= '0' && ar[i] <= '9') || ar[i] == '.' || ar[i] == ',' || (ar[i] == '-' && first)) {
str.push_back(ar[i]);
first = false;
if (i + 1 < arSize) {
if ((isdigit(ar[i + 1]) || ar[i + 1] == '.' || ar[i + 1] == ','))
continue;
}
arF.push_back(std::stof(str));
str.clear();
digit = false;
}
else { cout << endl << "Проверьте задание."; exit(1); }
}
else {
if(ar[i] != '\n')
deystv.push_back(ar[i]);
digit = true;
first = true;
}
}
str = calk(arF, deystv);
return str;
}
//*********************************************
void func(std::vector<char>& ar) {
std::vector<char>::iterator it = std::find(ar.begin(), ar.end(), '(');
if (it != ar.end()) {
std::vector<char> ar1{};
ar1.insert(ar1.begin(), it+1, ar.end());
func(ar1);
std::vector<char>::iterator it1 = std::find(ar1.begin(), ar1.end(), ')');
if (it1 != ar1.end()) {
std::vector<char> ar2{};
ar2.insert(ar2.begin(), ar1.begin(), it1);
//вычисляем значение в скобках
std::string str = parser(ar2);
ar1.erase(ar1.begin(), it1 + 1);
ar1.insert(ar1.begin(), str.begin(), str.end());
}
ar.erase(it, ar.end());
ar.insert(ar.end(), ar1.begin(), ar1.end());
}
}
int main()
{
setlocale(LC_ALL, "Russian");
std::ifstream myFile("example.txt", std::ios_base::in);
std::vector<char> ar{};
char c;
if (myFile) {
while (!myFile.eof()) {
while ((c = myFile.get()) == ' ');
if (c == '\n')break;
if (c != -1) { //конец файла?
ar.push_back(c);
}
}
cout << endl << endl;
arOut(ar);
cout << " = ";
func(ar);
cout << parser(ar);
}
else {
std::cout << "Hello World!\n";
cout << "File not found" << endl;
}
}