Untitled

 avatar
unknown
c_cpp
3 years ago
6.3 kB
5
Indexable
#include <iostream>
#include <string.h>
#include <locale>
#include <stdlib.h>
#include <math.h>
using namespace std;

// Функция для прямой подстановки
void forward_substitution(double *y, int n, double **L, double *b) {
	y[n] = {};
	double Sum;
	for (int i = 0; i< n; i++) {
		Sum = 0;
		for (int j = 0; j <= i-1 ;j++) {
			Sum+= L[i][j]* y[j];
		}
		y[i] = (b[i] - Sum);
	}
}
// Функция обратной подстановки
void reverse_substitution(double *x, int n, double **U, double *b) {
	x[n] = {};
	double Sum;
	for (int i = n - 1; i >= 0; i--) {
		Sum = 0;
		for (int j = i + 1; j <= n ;j++) {
			Sum+= U[i][j]* x[j];
		}
		x[i] = (b[i] - Sum) / U[i][i];
	}
}

// Функция для ввода/вывода матриц.
void inputOutputMatrix(int n, double **matrix, int mode) {
	if(mode < 2) cout << " ----------------" << endl;
	for (int i = 0; i < n ; i++) {
		for (int j = 0; j < n ; j++) {					
			if (mode == 0) {
				cout << " | Ввод | M[" << i <<  "][" << j << "] = ";
				cin >> matrix[i][j];
			} // mode - режим работы: 0 - ввод, 1 - вывод, 2 - заполнение единичной матрицы, 3 - заполнение нулевой.
			else if (mode == 1) {
				//cout << "M[" << i <<  "][" << j << "] = " << matrix[i][j] << " ";
				cout << matrix[i][j] << "   ";
				if (j == n - 1) cout << endl;
			}
			else if (mode>1) {
				if ((i == j) and (mode == 2)) {
					matrix[i][j] = 1;
				}
				else {
					matrix[i][j] = 0;
				}
			}
		}
	}
	if (mode < 2) cout << " ----------------" << endl;
}

// Функция для LU - разложения (прямая реализация по алгоритму)
void lu_decomposition(int n,double **L, double **U, double **A) {
	double Sum;
	int k;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			Sum = 0;					
			if (i<= j) {
				for (k = 0; k <= i-1; k++) {
					Sum += L[i][k] * U[k][j];
				}
				U[i][j] = A[i][j] - Sum ;
			}
			else if(i> j) {
				for (k = 0; k <= j-1; k++) {
					Sum += L[i][k] * U[k][j];
				}
				L[i][j] = (A[i][j] - Sum) / U[j][j];
			}
		}
	}
}

// Функция для решения СЛАУ.
void SLAU(int rows, double **L, double **U, double *x, double *y, double *b ) {
	forward_substitution(y,rows, L, b);
	reverse_substitution(x,rows, U, y);
}

//Функция для нахождения обратной матрицы.
void reverse_matrix(int rows, double **L, double **U, double *x, double *y, double **reverse) {
	for (int i = 0; i < rows; i++) {
		double b[rows] = {};
		b[i] = 1;
		SLAU(rows, L, U, x, y, b );
		for (int k = 0; k < rows; k++) {
			reverse[k][i] = x[k];
		}
	}
}

//Функция для умножения матрицы на вектор.
void key_multiplication(int rows, double **key, double *vector, double *response) {
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < rows; j ++) {
			response[i] += key[i][j] * vector[j];
		}
	}
}

//Функция для шифровки.
void hill_encryption(int rows, int wordSize, int dictSize, char *word, char *dict, double **key, double *response) {
	double vector[rows];
	int count = 0;
	for (int i = 0; i < wordSize; i++) {
		for (int k = 0; k < dictSize; k++) {
			if (word[i] == dict[k]) {
				vector[count] = k+1;
				count+=1;
			}
			if (count == 3) {
				count = 0;
				key_multiplication(rows, key, vector, response);
				for (int i = 0; i < rows; i ++) {
					cout << response[i] << " ";
					response[i] = 0;
				}
				double vector[rows];
			}
		}
	}
}

//Функция для разшифровки.
void hill_decryption(int rows, double **L, double **U, double *x, double *y, char *dict) {
	int length;
	cout << " Введите длину: " << endl;
	cin >> length;
	char word[length];
	double vector[rows];
	cout << " Введите зашифрованное сообщение: " << endl;
	int count = 0;
	int all_count = 0;
	for (int i = 0; i < length; i++) {
		cin >> vector[count];
		count+=1;
		if (count == 3) {
			cout << "ok";
			count = 0;
			SLAU(rows, L, U, x, y, vector);
			int index;
			for (int k = 0; k < rows; k++) {
				index = x[k];
				word[all_count] = dict[index-1];
				all_count += 1;
			}
			cout << endl;
		}
	}
	for (int i = 0; i < length; i++) {
		cout << word[i];
	}
}

int main(int argc, char** argv) {
	setlocale( LC_ALL,"Russian" );
	int rows = 3, cols = 3;
	char rus_letters[]{"абвгдеёжзийклмнопрстуфхцчшщъыьэюя ?.,"}; // Русский алфавит
	char word[]{"игорькабв"}; // Послед-ть символов для шифровки
	// Инициализация матриц.
	double **matrixA = new double *[rows];  // Матрица A.
	double **matrixL = new double *[rows];  // Матрица L.
	double **matrixU = new double *[rows];  // Матрица U.
	double **key = new double *[rows]; 	    // Матрица-ключ.
	double **reverse = new double *[rows];  // Обратная матрица.
	double matrixb[rows];
	double y[rows];
	double x[rows];
	double c[rows];
	double response[rows];
	for(int i = 0; i < rows; i++) {
		matrixA[i] = new double[cols];
		matrixL[i] = new double[cols];
		matrixU[i] = new double[cols];
		reverse[i] = new double[cols];
		key[i] = new double[cols];
	}
	// Ввод матриц A, L, U	
	inputOutputMatrix(rows, matrixL, 2); // Создание единичной матрицы L
	inputOutputMatrix(rows, matrixU, 3); // Создание нулевой матрицы U
	cout << endl << " Введите ключ-матрицу: " << endl;
	inputOutputMatrix(rows, key, 0);
	int mode;
	cout << endl << " Введите что необходимо сделать:" << endl << " 1.Зашифровать" << endl << " 2.Разшифровать " << endl;
	cin >> mode;
	if (mode == 1) {
		cout << " Результат:" << endl;
		cout << " ";
		hill_encryption(rows, sizeof(word) - 1, sizeof(rus_letters) - 1, word, rus_letters, key, response);
	}
	if (mode == 2) {
		lu_decomposition(rows, matrixL, matrixU, key);
		hill_decryption(rows, matrixL, matrixU, x, y, rus_letters);
	}

	return 0;
}