Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

PolynomialSimplification

.cpp
Скачиваний:
0
Добавлен:
19.06.2023
Размер:
7.86 Кб
Скачать
#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;
			}
		}
	}
}
Соседние файлы в предмете Программирование