【C++ 程序】 解线性方程组(Cramer法则)(分数形式结果)

f毕竟数学多用分数,所以修改了原程序:

程序

Source.cpp

#include <iostream>
#include <conio.h>
#include <Windows.h>
#include "Det.h"
#include "Fraction.h"
using namespace std;

int main()
{
	int num;
	unsigned m = 0;
	deque<deque<double>> mat;
	deque<deque<deque<double>>> D;

	// instruction
	cout << "Please input like this:\n"
		<< "a_11 * x_1 + a_12 * x_2 + ... + a_1n * x_n = b_1\n"
		<< "a_21 * x_1 + a_22 * x_2 + ... + a_2n * x_n = b_2\n"
		<< "...\n"
		<< "a_n1 * x_1 + a_n2 * x_2 + ... + a_nn * x_n = b_n"
		<< "\n" << endl;

	// input
	while (1)
	{
		deque<double> row;
		while (cin >> num)
		{
			row.push_back(num);
			if (getchar() == '\n') break;
		}
		mat.push_back(row);
		m = (row.size() > m) ? row.size() : m;
		if (mat.size() >= m - 1) break;
	}

	// hide the Console Cursor
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cci;
	GetConsoleCursorInfo(hOut, &cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(hOut, &cci);

	// calculate & print
	for (unsigned i = 0; i < m; i++)
	{
		deque<deque<double>> temp = mat; // D[m - 1][m]
		for (unsigned j = 0; j != m - 1; j++)
		{
			if (i) temp[j][i - 1] = mat[j][m - 1];
			temp[j].pop_back();
		}
		D.push_back(temp);
	}
	double D0 = det_is(D[0]);
	if (D0 != 0)
	{
		cout << "\n-------------------------------------------------------------------------\n"
			<< "By default you view the solution in the FRACTION form.\n"
			<< "You can switch to DECIMAL by any keyboard press except Enter.\n"
			<< "Press Enter to end the program.\n"
			<< "-------------------------------------------------------------------------\n" << endl;
		for (unsigned i = 1; i < m; i++)
		{
			cout << "x_" << i << " = " << decimal_to_fraction(det_is(D[i]) / D0) << endl;
		}
		while (1)
		{
			if (_kbhit())
			{
				if (_getch() != '\r') // not Enter
				{
					// return to the front of the line (\r)
					// cover the initial input by pressing the keyboard
					cout << "\r\t\r\n-------------------------------------------------------------------------\n" << endl;
					for (unsigned i = 1; i < m; i++)
					{
						cout << "x_" << i << " = " << det_is(D[i]) / D0 << endl;
					}
				}
				cout << "\n-------------------------------------------------------------------------" << endl;
				break;
			}
		}
	}
	else
	{
		cout << "\n-------------------------------------------------------------------------" << endl;
		cout << "\nNo finite solution!" << endl;
		cout << "\n-------------------------------------------------------------------------" << endl;
	}
	return 0;
}

Fraction.h

#ifndef _FRACTION_
#define _FRACTION_
#include <string>
#include <vector>

std::string decimal_to_fraction(double n)
{
	std::string fra = "";
	std::string sgn = (n >= 0) ? "" : "-";
	n = fabs(n);
	double epsilon = 1E-10;
	if (n - static_cast<int>(n) < epsilon)
	{
		fra = std::to_string(static_cast<int>(n));
		return fra;
	}
	else if (n - static_cast<int>(n) > 1 - epsilon)
	{
		fra = std::to_string(static_cast<int>(n) + 1);
		return fra;
	}
	else
	{
		std::vector<int> denominator;
		for (int i = 2; i <= 100000; i++)
			denominator.push_back(i);
		for (auto c : denominator) // every number within 100000
		{
			if (c * n - static_cast<int>(c * n) < epsilon)
			{
				fra = sgn + std::to_string(static_cast<int>(c * n)) + "/" + std::to_string(c);
				return fra;
			}
			if (c * n - static_cast<int>(c * n) > 1 - epsilon)
			{
				fra = sgn + std::to_string(static_cast<int>(c * n) + 1) + "/" + std::to_string(c);
				return fra;
			}
		}
	}
	return std::to_string(n);
}

#endif // !_FRACTION_

Det.h
见我的博客 【C++ 程序】 行列式

输出示例

Output

分析

  • 输出分数原理:判断分数值与小数值相差不超过一个极小的值,此处即epsilon。特别注意负数时候的情况!
  • \r回车,回到一行最前端。(事实上Enter=\r\n,不过C++中\n就是\r\n
  • 其他详见我的博客 【C++ 程序】 解线性方程组(Cramer法则)

ALL RIGHTS RESERVED © 2020 Teddy van Jerry
欢迎转载,转载请注明出处。


See also

Teddy van Jerry 的导航页

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值