Добавил:
jetu
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:PolynomialSimplification
.cpp#include <iostream>
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#define MAX_DEGREE 99
class Polynomial {
private:
int value[MAX_DEGREE + 1] = { 0,0,0,0,0,0,0,0,0,0 };
public:
int get_factor(int degree) {
if (degree < 0) degree *= -1;
return value[degree % (MAX_DEGREE + 1)];
}
void set_factor(int degree, int val) {
if (degree < 0) degree *= -1;
value[degree % (MAX_DEGREE + 1)] = val;
}
Polynomial operator + (Polynomial b) {
Polynomial result;
for (int i = 0; i < (MAX_DEGREE + 1); i++)
result.value[i] = value[i] + b.value[i];
return result;
}
Polynomial operator - (Polynomial b) {
Polynomial result;
for (int i = 0; i < (MAX_DEGREE + 1); i++)
result.value[i] = value[i] - b.value[i];
return result;
}
Polynomial operator * (Polynomial b) {
Polynomial result;
for (int i = 0; i < (MAX_DEGREE + 1); i++)
for (int j = 0; j < (MAX_DEGREE + 1); j++) {
if (i + j < (MAX_DEGREE + 1))
result.value[i + j] += value[i] * b.value[j];
else if (value[i] != 0 and b.value[j] != 0) {
throw L"Ожидалась степень многочлена, не превышающая 99-ю";
}
}
return result;
}
void operator += (Polynomial b) {
*this = *this + b;
}
void operator -= (Polynomial b) {
*this = *this - b;
}
void operator *= (Polynomial b) {
*this = *this * b;
}
};
#define SIZE 120
#define KEY_BACKSPACE 8
#define FUNC_KEYS 0
#define CONTROL_KEYS 224
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_DELETE 83
wchar_t expr[SIZE];
wchar_t result[10];
int index = 0;
int position = 0;
int symbols = 0;
int error_pos = 0;
bool update_screen = true;
Polynomial parse_addition();
Polynomial parse_negative();
bool is_number(wchar_t ch) {
return ch >= '0' and ch <= '9';
}
int parse_number() {
int value = expr[index] - '0';
if (is_number(expr[index]))
++index;
else {
throw L"Ожидалось число";
}
while (index < SIZE and is_number(expr[index])) {
value = value * 10 + expr[index] - '0';
++index;
}
return value;
}
Polynomial parse_value() {
Polynomial result;
if (expr[index] == 'x') {
++index;
result.set_factor(1, 1);
}
else
result.set_factor(0, parse_number());
return result;
}
Polynomial parse_parenthesis() {
if (expr[index] == '(') {
++index;
Polynomial value = parse_addition();
if (expr[index] != ')') {
throw L"Ожидалась закрывающая скобка";
}
++index;
return value;
}
return parse_value();
}
Polynomial parse_exponentiation() {
Polynomial value = parse_parenthesis();
while (expr[index] == L'^') {
int pow_index = index;
++index;
Polynomial power = parse_negative();
for (int i = 1; i < MAX_DEGREE; i++)
if (power.get_factor(i) != 0) {
index = pow_index;
throw L"Ожидалась степень с выражением, не содержащим «x»";
}
if (power.get_factor(0) > 0) {
Polynomial factor = value;
for (int i = 1; i < power.get_factor(0); i++) {
value *= factor;
}
}
else if (power.get_factor(0) == 0) {
for (int i = 1; i < MAX_DEGREE; i++) {
value.set_factor(i, 0);
}
value.set_factor(0, 1);
}
else {
index = pow_index;
throw L"Ожидалась степень с неотрицательным значением";
}
}
return value;
}
Polynomial parse_negative() {
if (expr[index] == L'–') {
++index;
Polynomial negative;
negative.set_factor(0, -1);
return negative * parse_exponentiation();
}
if (expr[index] == L'+' and index == 0)
++index;
return parse_exponentiation();
}
Polynomial parse_multiplication() {
Polynomial value = parse_negative();
while (expr[index] == L'·') {
++index;
value *= parse_negative();
}
return value;
}
Polynomial parse_addition() {
Polynomial value = parse_multiplication();
while (true) {
if (expr[index] == '+') {
++index;
value += parse_multiplication();
}
else if (expr[index] == L'–') {
++index;
value -= parse_multiplication();
}
else
break;
}
return value;
}
Polynomial parse() {
index = 0;
Polynomial value = parse_addition();
if (index < symbols) {
throw L"Неожиданный символ";
}
return value;
}
void print_in_superscript(int number) {
if (number == 0)
wprintf(L"⁰");
else if (number == 1)
wprintf(L"¹");
else if (number == 2)
wprintf(L"²");
else if (number == 3)
wprintf(L"³");
else if (number >= 4 and number <= 9)
wprintf(L"%c", number - 4 + L'⁴');
else if (number >= 10) {
print_in_superscript(number / 10);
print_in_superscript(number % 10);
}
}
int main()
{
(void)_setmode(_fileno(stdout), _O_U16TEXT);
/*
* Переменные
*/
int input;
for (int i = 0; i < SIZE; i++)
expr[i] = L'\0';
//wprintf(L"˄ˆ");
while (true) {
/*
* Вывод на экран
*/
if (update_screen) {
system("cls");
wprintf(L"УПРОЩЕНИЕ МНОГОЧЛЕНА\nВведите выражение: \n");
for (int i = 0; i < SIZE; i++)
wprintf(L"%c", expr[i]);
try {
Polynomial result = parse();
bool printed = false;
if (position < SIZE)
wprintf(L"\n%*c", (position + 1), L'‾');
else
wprintf(L"\n");
wprintf(L"\nРезультат: ");
for (int i = MAX_DEGREE; i >= 0; i--) {
int a = result.get_factor(i);
if (a == -1 and i > 0)
wprintf(L"–");
if (printed and a > 0)
wprintf(L"+");
if (a != 0) {
if ((a != 1 and a != -1) or i == 0) {
if (a > 0)
wprintf(L"%d", a);
if (a < 0)
wprintf(L"–%d", -a);
}
if (i > 0)
wprintf(L"x");
if (i >= 2)
print_in_superscript(i);
printed = true;
}
}
if (!printed)
wprintf(L"0");
}
catch (const wchar_t* msg) {
if (position < index)
wprintf(L"%*c%*c\n", (position + 1), L'‾', (index - position), L'↑');
else if (position > index)
wprintf(L"%*c%*c\n", (index + 1), L'↑', (position - index), L'‾');
else
wprintf(L"%*c\n", (index + 1), L'˄');
wprintf(L"%*s", (index + 1), msg);
}
wprintf(L"\n");
update_screen = false;
}
/*
* Управление
*/
input = _getwch();
if (input == L'ч')
input = 'x';
else if (input == ':')
input = '^';
else if (input == '*')
input = L'·';
else if (input == '-')
input = L'–';
if (input == FUNC_KEYS)
(void)_getwch();
else if (input == CONTROL_KEYS) {
input = _getwch();
if (input == KEY_LEFT and position > 0) {
--position;
update_screen = true;
}
else if (input == KEY_RIGHT and position < symbols) {
++position;
update_screen = true;
}
else if (input == KEY_DELETE and position < symbols) {
for (int i = position; i < SIZE - 1; i++)
expr[i] = expr[i + 1];
expr[SIZE - 1] = '\0';
--symbols;
update_screen = true;
}
}
else if (input == KEY_BACKSPACE and position > 0) {
for (int i = position - 1; i < SIZE - 1; i++)
expr[i] = expr[i + 1];
expr[SIZE - 1] = '\0';
--position;
--symbols;
update_screen = true;
}
else {
if (symbols < SIZE and position < SIZE and (
is_number(input)
or input == 'x'
or input == '+'
or input == L'–'
or input == L'·'
or input == '^'
or input == '('
or input == ')')) {
for (int i = SIZE - 1; i >= position; i--)
expr[i] = expr[i - 1];
expr[position] = input;
++position;
++symbols;
update_screen = true;
}
}
}
}
Соседние файлы в предмете Программирование