IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Rovnice a determinant

vypočítává kořeny soustavy rovnc a determinant matice

cpp

// Rovnice a determinant.cpp : Defines the entry point for the console application.
//

#include<iostream>
#include<string>
#include<fstream>
#include<clocale>
#include<Windows.h>
#include<sstream>
#include<conio.h>
#include<iomanip>

using namespace std;
void Gotoxy(int x, int y) {
	COORD pos = {x, y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

double determinant(double** _matrix, int sizeX) {
	//vytvoøení duplicitní matice, aby se nesmazaly hodnoty
	double** matrix = new double*[sizeX];
	for (int i = 0; i < sizeX; i++) {
	matrix[i] = new double[sizeX];
	}

	//kopírování hodnot

	for (int x = 0; x < sizeX; x++) {
		for (int y = 0; y < sizeX; y++) {
			matrix[x][y] = _matrix[x][y];
		}
	}

	//poèítání determinantu pomocí gaussovy eliminace, souèet prvkù na hlavní diagonále dá dohromady determinant.
	for (int radek = 0; radek < sizeX - 1; radek++) {
		if (matrix[radek][radek] == 0) {
			// hledani prvniho radku ktery nezacina nulou
			for (int _radek = radek + 1; _radek < sizeX; _radek++) {
				if (matrix[_radek][radek] != 0) { // nalezen nenulovy radek, prehozeni s aktivnim radkem
					double pomoc;
					for (int _sloupec = radek; _sloupec < sizeX + 1; _sloupec++) {
						pomoc = matrix[radek][_sloupec];
						matrix[radek][_sloupec] = matrix[_radek][_sloupec];
						matrix[_radek][_sloupec] = pomoc;
					}
					break;
				}
			}
		}

		for (int _radek = radek + 1; _radek < sizeX; _radek++) {
			// kdyz nebyl nalezen radek nezacinajici nulou - > determinant je roven nule
			if (matrix[radek][radek] == 0) {
				return 0;
			}

			double pomer = matrix[_radek][radek] / matrix[radek][radek];

			// odeètení / pøiètení øádku
			matrix[_radek][radek] = 0; //explicitnì, kvùli nedokonalostem uchovávání v dat. typu double.
			for (int sloupec = radek + 1; sloupec < sizeX + 1; sloupec++) {
				matrix[_radek][sloupec] -= matrix[radek][sloupec] * pomer;

			}
		}
	}
	double determinant = 1;
	for (int i = 0; i < sizeX; i++) {
		determinant *= matrix[i][i];
	}

	//mazání dynamicky vytvoøených polí vyhazuje chybu (dùvod?)
	/*for (int i = 0; i < sizeX; i++) {
		delete[] matrix[i];
	}
	delete[] matrix;*/

	if (determinant == 0) return 0; // kvùli "záporné nule"

	return determinant;
}

void PrintMatrix(double** matrix, int sizeX, bool extended) {
	stringstream ss;
	for (int x = 0; x < sizeX; x++) {
		for (int y = 0; y < sizeX; y++) {
			ss << setw(6) << setprecision(6) << matrix[x][y] << " ";
		}
		if (extended) ss << "| " << setw(6) << setprecision(9) << matrix[x][sizeX];
		ss << endl;
	}
	cout << ss.str();
}

void GaussElimination(double** soustava, int pocetNeznamych) {
	bool solvable = true;
	system("cls");
	cout << "Pùvodní matice soustavy:\n";
	PrintMatrix(soustava, pocetNeznamych, true);

	// primy chod
	for (int radek = 0; radek < pocetNeznamych - 1; radek++) {
		if (soustava[radek][radek] == 0) {
			// hledani prvniho radku ktery nezacina nulou
			for (int _radek = radek + 1; _radek < pocetNeznamych; _radek++) {
				if (soustava[_radek][radek] != 0) { // nalezen nenulovy radek, prehozeni s aktivnim radkem
					double pomoc;
					for (int _sloupec = radek; _sloupec < pocetNeznamych + 1; _sloupec++) {
						pomoc = soustava[radek][_sloupec];
						soustava[radek][_sloupec] = soustava[_radek][_sloupec];
						soustava[_radek][_sloupec] = pomoc;
					}
					break;
				}
			}
		}

		for (int _radek = radek + 1; _radek < pocetNeznamych; _radek++) {
			// kdyz nebyl nalezen radek nezacinajici nulou
			if (soustava[radek][radek] == 0) {
				break;
			}

			double pomer = soustava[_radek][radek] / soustava[radek][radek];

			// odeètení / pøiètení øádku
			soustava[_radek][radek] = 0; //explicitnì, kvùli nedokonalostem uchovávání v dat. typu double.
			for (int sloupec = radek + 1; sloupec < pocetNeznamych + 1; sloupec++) {
				soustava[_radek][sloupec] -= soustava[radek][sloupec] * pomer;

			}
		}
	}

	cout << "\nMatice soustavy po pøímém chodu gausovy eliminace:\n";
	PrintMatrix(soustava, pocetNeznamych, true);

	// zpetny chod
	for (int radek = pocetNeznamych - 1; radek > 0; radek--) {
		for (int _radek = radek - 1; _radek >= 0; _radek--) {
			if (soustava[radek][radek] == 0) {
				if (soustava[radek][pocetNeznamych] != 0) cout << "\nSoustava nema reseni";
				else cout << "\nSoustava ma nekonecne mnoho reseni, zde je výsledná matice soustavy:\n";
				PrintMatrix(soustava, pocetNeznamych, true);
				solvable = false;
				break;
			}

			double pomer = soustava[_radek][radek] / soustava[radek][radek];

			for (int sloupec = pocetNeznamych; sloupec >= radek; sloupec--) {
				soustava[_radek][sloupec] -= pomer * soustava[radek][sloupec];
			}

			soustava[_radek][radek] = 0; //explicitnì, kvùli nedokonalostem uchovávání v dat. typu double.
		}
		if (!solvable) break;
	}
	// normovani vysledku
	if (solvable) {
		cout << "\nMatice soustavy po zpìtném chodu gausovy eliminace:\n";
		PrintMatrix(soustava, pocetNeznamych, true);

		for (int radek = 0; radek < pocetNeznamych; radek++) {
			soustava[radek][pocetNeznamych] /= soustava[radek][radek];
			soustava[radek][radek] = 1;
		}

		cout << "\nMatice soustavy po znormování:\n";
		PrintMatrix(soustava, pocetNeznamych, true);

		cout << "\nKoreny soustavy rovnic:\n";
		for (int i = 0; i < pocetNeznamych; i++)
			cout << soustava[i][pocetNeznamych] << "\n";
	}

	cout << "\nStisknìte libovolnou klávesu pro návrat do hlavního menu.\n";
	_getch();
}

void Kramerius(double** soustava, int pocetNeznamych) {
	double determinantZakladu;
	system("cls");
	cout << "Pùvodní matice soustavy:\n";
	PrintMatrix(soustava, pocetNeznamych, true);

	cout << "\nZákladní matice:\n";
	PrintMatrix(soustava, pocetNeznamych, false);
	determinantZakladu = determinant(soustava, pocetNeznamych);
	cout << "Determinant = " << determinantZakladu << endl;

	if (determinantZakladu == 0) {
		cout << "\nSoustava má nekoneènì mnoho a nebo žádné øešení.\n\nStisknìte libovolnou klávesu pro návrat do hlavního menu.";
		_getch();
	}
	else {
		// pomocná matice
		double** matrix = new double*[pocetNeznamych];
		for (int i = 0; i < pocetNeznamych; i++) {
			matrix[i] = new double[pocetNeznamych];
		}

		// pole pro uložení øešení
		double* roots = new double[pocetNeznamych];

		//zkopírování matice
		for (int radek = 0; radek < pocetNeznamych; radek++) // prvni sloupec je prohozen
			matrix[radek][0] = soustava[radek][pocetNeznamych];
		for (int sloupec = 1; sloupec < pocetNeznamych; sloupec++)  // zbylé sloupce
			for (int radek = 0; radek < pocetNeznamych; radek++)
				matrix[radek][sloupec] = soustava[radek][sloupec];

		// první neznámá
		cout << "\n1. neznámá - pøíslušná matice: \n";
		PrintMatrix(matrix, pocetNeznamych, false);
		roots[0] = determinant(matrix, pocetNeznamych);
		cout << "Determinant = " << roots[0];
		roots[0] /= determinantZakladu;
		cout << "\nHodnota = " << roots[0] << endl << endl;

		// výpoètová smyèka pro další neznámé
		for (int neznama = 1; neznama < pocetNeznamych; neznama++) {

			//zkopírování matice
			for (int sloupec = 0; sloupec < pocetNeznamych; sloupec++) 
				for (int radek = 0; radek < pocetNeznamych; radek++)
					matrix[radek][sloupec] = soustava[radek][sloupec];

			//kopírování urèitého sloupce
			for (int radek = 0; radek < pocetNeznamych; radek++) {
				matrix[radek][neznama] = soustava[radek][pocetNeznamych];
			}

			// výpis / výpoèet
			cout << neznama + 1 << ". neznámá - pøíslušná matice: \n";
			PrintMatrix(matrix, pocetNeznamych, false);
			roots[neznama] = determinant(matrix, pocetNeznamych);
			cout << "Determinant = " << roots[neznama];
			roots[neznama] /= determinantZakladu;
			cout << "\nHodnota = " << roots[neznama] << endl << endl;
		}
		cout << "Koøeny soustavy rovnic:\n";
		for (int i = 0; i < pocetNeznamych; i++) {
			cout << roots[i] << endl;
		}
		cout << "\nStisknìte libovolnou klávesu pro návrat do hlavního menu.\n";
		_getch();

		//mazání dynamicky vytvoøených polí vyhazuje chybu (dùvod?)
		/*for (int i = 0; i < pocetNeznamych; i++) {
		delete[] matrix[i];
		}
		delete[] matrix;
		delete[] roots;*/
	}
}

void RandInput(double** matrix, int sizeX, bool extended) {
	string input;
	int min, max;

	do {
		system("cls");
		cout << "Zadejte minimální hodnotu: ";
		getline(cin, input);
		if (!atoi(input.c_str())) {
			cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
			_getch();
		}
		else min = atoi(input.c_str());
	} while (!(atoi(input.c_str()) || input == "0"));
	max = min - 1;
	do {
		system("cls");
		cout << "Zadejte maximální hodnotu: ";
		getline(cin, input);
		if (!atoi(input.c_str()) || atoi(input.c_str()) < min) {
			cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
			_getch();
		}
		else max = atoi(input.c_str());
	} while (!(atoi(input.c_str()) || (input == "0")) || min > max);

	for (int x = 0; x < sizeX; x++) {
		for (int y = 0; y < sizeX; y++) {
			matrix[x][y] = min + rand() % (max - min + 1);
		}
		if (extended) matrix[x][sizeX] = min + rand() % (max - min + 1);
	}
}

bool FileInput(double** matrix, int sizeX, bool extended) {
	system("cls");
	bool validInput = true;
	string inputLine;
	string number;
	stringstream buffer;
	fstream file;
	file.open("input.txt");
	if (file.is_open()) {
		for (int x = 0; x < sizeX; x++) {
			// naètení øádku a pøipravení na zpracování
			getline(file, inputLine);
			stringstream buffer(inputLine);
			for (int y = 0; y < sizeX; y++) {
				if (getline(buffer, number, ' ')) { //pokud je na øádku dosud nepøeètené èíslo
					while (number == "") {
						getline(buffer, number, ' ');
					}
					if (atof(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
						matrix[x][y] = atof(number.c_str());
					else { // pokud se nejedná o èíslo
						cout << "Na øádku " << x + 1 << " na pozici " << y + 1 << " se vyskytuje neèíslo.\n";
						validInput = false;
						break;
					}
				}
				else {
					cout << "Na øádku " << x + 1 << " je nedostateèný poèet èísel.\n";
					validInput = false;
					break;
				}
			}
			if (extended && validInput) { // pokud se naèítá rozšíøená matice
				if (getline(buffer, number)) { // je na øádku další èíslo
					if (atof(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
						matrix[x][sizeX] = atof(number.c_str());
					else {
						cout << "Na øádku " << x + 1 << " na pozici " << sizeX + 1 << " se vyskytuje neèíslo.\n";
						validInput = false;
					}
				}
				else {
					cout << "Na øádku " << x + 1 << " je nedostateèný poèet èísel.\n";
					validInput = false;
				}
			}
			if (!validInput) {
				cout << "Stisknìte libovolnou klávesu pro návrat do pøedchozí nabídky.\n";
				_getch();
				return false;
			}
		}
	}
	else {
		cout << "Soubor nemohl být otevøen, zkontrolujte, zda se nachází ve složce s .exe\n"
			<< "Stisknìte libovolnou klávesu pro návrat do pøedchozí nabídky.\n";
		_getch();
		return false;
	}
	return true;
}

void ManualInput(double** matrix, int sizeX, bool extended) {
	bool validInput;
	string inputLine, number;
	system("cls");
	cout << "Zadejte jednotlivé " << ((extended) ? "koeficienty soustavy rovnic" : "øádky matice") << endl;
	for (int x = 0; x < sizeX; x++) {
		// naètení øádku a pøipravení na zpracování
		getline(cin, inputLine);
		stringstream buffer(inputLine);
		validInput = true;

		for (int y = 0; y < sizeX; y++) {
			if (getline(buffer, number, ' ')) { //pokud je na øádku dosud nepøeètené èíslo
				if (stod(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
					matrix[x][y] = stod(number.c_str());
				else { // pokud se nejedná o èíslo
					cout << "Na øádku se vyskytuje neèíslo, opakujte zadání øádku.\n";
					x -= 1;
					validInput = false;
					break;
				}
			}
			else {
				cout << "Nedostateèný poèet èísel, " << (((extended ? sizeX + 1 : sizeX) < 5) ? "jsou" : "je") << " tøeba " << (extended ? sizeX + 1 : sizeX) << (((extended ? sizeX + 1 : sizeX) < 5) ? " èísla" : " èísel") << " na øádek. Zadejte øádek znovu.\n";
				x -= 1;
				validInput = false;
				break;
			}
		}
		if (extended && validInput) { // pokud se naèítá rozšíøená matice
			if (getline(buffer, number, ' ')) { // je na øádku další èíslo
				if (stod(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
					matrix[x][sizeX] = stod(number.c_str());
				else {
					cout << "Na øádku se vyskytuje neèíslo, opakujte zadání øádku.\n";
					x -= 1;
				}
			}
			else {
				cout << "Nedostateèný poèet èísel, je tøeba " << (extended ? sizeX + 1 : sizeX) << (((extended ? sizeX + 1 : sizeX) < 5) ? " èísla" : " èísel") << " na øádek. Zadejte øádek znovu.\n";
				x -= 1;
			}
		}
	}
}

void LinRovnice() {
	bool inputSuccess = false, fileInputSuccess = true;
	double** soustava;
	string input;
	int pocetNeznamych;
	do {
		system("cls");
		cout << "Zadejte poèet neznámých v soustavì rovnic: ";
		getline(cin, input);
		pocetNeznamych = atoi(input.c_str());
		if (!pocetNeznamych) {
			cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
			_getch();
		}
	} while (!pocetNeznamych);

	// vytvoøení dynamického pole
	soustava = new double*[pocetNeznamych];
	for (int i = 0; i < pocetNeznamych; i++)
		soustava[i] = new double[pocetNeznamych + 1];
	do {
		inputSuccess = false;
		system("cls");
		cout << "Øešení soustavy lineárních rovnic o " << pocetNeznamych << " neznámých. Zadejte zpùsob zadání:\n"
			<< " - 1 - Ruèní zadání koeficientù\n"
			<< " - 2 - Naètení ze souboru \"input.txt\"\n"
			<< " - 3 - Zvolení náhodných èísel v urèitém rozsahu\n"
			<< " - 4 - Návrat do hlavního menu\n";
		cout << "Zadejte volbu: ";
		while (!inputSuccess) {
			switch (_getch()) {
				case '1':
					ManualInput(soustava, pocetNeznamych, true);
					inputSuccess = fileInputSuccess = true;
					break;
				case '2':
					fileInputSuccess = FileInput(soustava, pocetNeznamych, true);
					inputSuccess = true;
					break;
				case '3':
					RandInput(soustava, pocetNeznamych, true);
					inputSuccess = fileInputSuccess = true;
					break;
				case '4':
					return;
				default:
					inputSuccess = false;
					break;
			}
		}
	} while (!inputSuccess || !fileInputSuccess);
	system("cls");
	cout << "Vyberte zpùsob øešení soustavy:\n"
		<< " - 1 - Gaussova eliminaèní metoda (pøímý a zpìtný chod)\n"
		<< " - 2 - Kramerovo pravidlo (pomocí determinantu matice)\n"
		<< "Zadejte volbu: ";
	while (true) {
		switch (_getch()) {
			case '1':
				GaussElimination(soustava, pocetNeznamych);
				for (int i = 0; i < pocetNeznamych; i++)
					delete[] soustava[i];
				delete[] soustava;
				return;
			case '2':
				Kramerius(soustava, pocetNeznamych);
				for (int i = 0; i < pocetNeznamych; i++)
					delete[] soustava[i];
				delete[] soustava;
				return;
			default:
				break;
		}
	}
	return;
}

void DeterminantMatrix() {
	bool inputSuccess = false;
	double ** matrix;
	int size;
	string input;
	do {
		system("cls");
		cout << "Zadejte øád matice: ";
		getline(cin, input);
		size = atoi(input.c_str());
		if (!size) {
			cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
			_getch();
		}
	} while (!size);

	// vytvoøení dynamického pole
	matrix = new double*[size];
	for (int i = 0; i < size; i++)
		matrix[i] = new double[size];
	bool fileInputSuccess = true;
	do {
		inputSuccess = false;
		system("cls");
		cout << "Zadejte zpùsob zadání:\n"
			<< " - 1 - Ruèní zadání øádkù matice\n"
			<< " - 2 - Naètení ze souboru \"input.txt\"\n"
			<< " - 3 - Zvolení náhodných èísel v urèitém rozsahu\n"
			<< " - 4 - Návrat do hlavního menu\n";
		cout << "Zadejte volbu: ";
		while (!inputSuccess) {
			switch (_getch()) {
				case '1':
					ManualInput(matrix, size, false);
					inputSuccess = fileInputSuccess = true;
					break;
				case '2':
					fileInputSuccess = FileInput(matrix, size, false);
					inputSuccess = true;
					break;
				case '3':
					RandInput(matrix, size, false);
					inputSuccess = fileInputSuccess = true;
					break;
				case '4':
					return;
				default:
					inputSuccess = false;
					break;
			}
		}
	} while (!inputSuccess || !fileInputSuccess);

	system("cls");
	cout << "Zadaná matice:\n";
	PrintMatrix(matrix, size, false);
	cout << endl << "Determinant = " << determinant(matrix, size) << endl << endl;
	cout << "Stisknìte libovolnou klávesu pro návrat do hlavního menu.\n";

	//mazání dynamicky vytvoøených polí vyhazuje chybu (dùvod?)
	/*for (int i = 0; i < size; i++) {
	delete[] matrix[i];
	}
	delete[] matrix;*/
	_getch();
	return;
}

int main(int argc, string args[]) {
	// nastavení podpory diakritiky - WIN only
	SetConsoleOutputCP(1250);

	bool run = true, inputSuccess;
	while (run) {
		system("cls");
		// nametag
		Gotoxy(110, 25);
		cout << "Radek Zikmund, ètvrtá, 2014";
		Gotoxy(0, 0);

		inputSuccess = false;
		cout << "Program na øešení soustav lineárních rovnic a výpoètu determinantu matice.\n"
			<< " - 1 - Øešení lineárních rovnic\n"
			<< " - 2 - Výpoèet determinantu matice\n"
			<< " - 3 - Ukonèení programu\n";
		cout << "Zadejte volbu: ";
		while (!inputSuccess && run) {
			switch (_getch()) {
				case '1':
					LinRovnice();
					inputSuccess = true;
					break;
				case '2':
					DeterminantMatrix();
					inputSuccess = true;
					break;
				case '3':
					run = false;
					break;
				default:
					break;
			}
		}
	}
	return 0;
}

Neformátovaný

Přidáno: 8.12.2014
Expirace: Neuvedeno

Avatar
Autor: Ziki
Aktivity