- •Список требований заказчика
- •Программа-генератор
- •Программа-вычислитель
- •Функциональная спецификация Программа-генератор polgen.Exe
- •Программа-вычислитель polsolve.Exe
- •Проектная спецификация Программа-генератор polgen.Exe
- •Программа-вычислитель polsolve.Exe
- •Эксплуатационная документация к программе-генератору polgen.Exe
- •К программе-вычислителю polsolve.Exe
- •Код программы Программа polgen.Exe Файл maincode.Cpp
- •Программа polsolve.Exe Файл maincode.Cpp
Программа polsolve.Exe Файл maincode.Cpp
#include <iostream>
#include <string>
#include <sstream>
#include <deque>
#include <assert.h>
using namespace std;
deque<string> inputsplit (string paramstr);
bool roughcheck (deque<string> &srcdeq, string argarr);
string parseargs (char *args[], int argcount);
void evaluate (deque<string> &srcdeq, string argarr);
string NOR (string a, string b);
void main (int argc, char *argv[])
{
if (argc == 1)
{
::cerr << "Variables should be determined! Program will exit\n";
assert (0);
}
else
{
//входную последовательность записываем в string переменную
string inputstr;
::getline (cin, inputstr);
//с помощью функции разбиения формируем дэк
deque<string> mydeq;
mydeq = inputsplit (inputstr);
//приводим к удобному типу список параметров командной строки
string argarr = parseargs (argv, argc);
//грубая проверка списка параметров и дэка
if (roughcheck (mydeq, argarr))
{
//вычисление логического выражения в обратной польской нотации
evaluate (mydeq, argarr);
if (mydeq.size() == 1)
cout << mydeq[0] << endl;
else
cerr << "Something went wrong, probably logical error\n";
}
}
//system("pause");
}
//функция разбиения входного string на элементы дэка, формирование дэка
deque<string> inputsplit (string paramstr)
{
deque<string> resultlst;
stringstream mystrs(paramstr);
string buffer;
while (mystrs >> buffer)
resultlst.push_back(buffer);
return resultlst;
}
//грубая проверка введенных параметров командной строки, а затем и выражения в польской нотации
bool roughcheck (deque<string> &srcdeq, string argarr)
{
bool checkresult = true;
string tempstr;
//строка с перечислением переменных, указанных в параметрах командной строки
string vararr;
::stringstream myss(argarr);
//Сперва проанализируем введенные параметры командной строки
while (myss >> tempstr)
{
if (tempstr.find_first_of('=') == tempstr.find_last_of('=') && (tempstr[tempstr.size() - 1] == '1' || tempstr[tempstr.size() - 1] == '0'))
{
vararr += tempstr.substr(0, tempstr.find_first_of('='));
vararr.push_back(' ');
continue;
}
checkresult = false;
break;
}
//Если с параметрами/переменными всё в порядке, идем дальше и проверяем введенную последовательность
if (checkresult)
{
//Если меньше трех элементов в списке, то очевидно, что ввод некорректен
if (srcdeq.size() < 3)
{
cerr << "\tIncorrect expression, application will exit\n";
checkresult = false;
}
//Теперь проверим, чтобы у нас не было ничего, кроме переменных, нулей и стрелок Пирса
if (checkresult)
{
for (size_t i = 0; i + 1 <= srcdeq.size() && checkresult; ++i)
{
checkresult = false;
//рассматриваемая ячейка дэка содержит только стрелку Пирса или только ноль
if (srcdeq[i].size() == 1 && srcdeq[i].find_first_not_of("0_") == string::npos)
checkresult = true;
//элемент - переменная. Она должна быть в списке, составленным из параметров командной строки
else if (vararr.find(srcdeq[i]) != string::npos)
checkresult = true;
else
cerr << "Input sequence didn't pass the rough check function. Application will exit\n";
}
}
}
assert (checkresult);
return checkresult;
}
//преобразование char массива параметров командной строки в string
string parseargs (char *args[], int argcount)
{
//vararr - массив имен переменых
string vararr;
//записываем аргументы (кроме нулевого) в string-переменную для последующего анализа
//Какой же изврат... но мозги опухли, ничего лучше придумать не смогли
for (int i = 1; i <= argcount - 1; ++i)
{
for (size_t j = 0; j + 1 <= ::strlen(args[i]); ++j)
vararr.push_back(args[i][j]);
vararr.push_back(' ');
}
vararr.pop_back();
return vararr;
}
void evaluate (deque<string> &srcdeq, string argarr)
{
//Сначала заменим все переменные на 1 или 0 согласно параметрам командной строки
for (size_t j = 0; j + 1 <= srcdeq.size(); ++j)
{
if (srcdeq[j] != "_" && srcdeq[j].find_first_of("10") == string::npos)
{
//список аргументов ранне прошел проверку, поэтому наш 1 или 0 находится сразу после первого слева знака "="
size_t idx = argarr.find(srcdeq[j]) + srcdeq[j].length() + 1;
srcdeq[j] = argarr[idx];
}
}
//флаг остановит процесс, если на одном проходе не будет произведено вычисление
//как правило, это свидетельствует о логической ошибке в построении входного выражения
bool flag = true;
size_t i = 0;
//несколько раз пробегаем дэк слева направо
while (srcdeq.size() >= 3 && flag)
{
flag = false;
i = 0;
//цикл пробега по элементам
while (i + 3 <= srcdeq.size() && srcdeq.size() >= 3)
{
if (srcdeq[i].find_first_of("10") != string::npos && srcdeq[i + 1].find_first_of("10") != string::npos && srcdeq[i + 2] == "_")
{
srcdeq[i + 2] = NOR (srcdeq[i], srcdeq[i + 1]);
srcdeq.erase (srcdeq.begin() + i, srcdeq.begin() + i + 2);
flag = true;
if (i != 0)
i--;
}
else
{
i++;
}
}
}
}
//функция стрелки Пирса
string NOR (string a, string b)
{
string result = "0";
if (a == "0" && b == "0")
result = "1";
return result;
}
