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++ 程序】 行列式。
输出示例
分析
- 输出分数原理:判断分数值与小数值相差不超过一个极小的值,此处即epsilon。特别注意负数时候的情况!
\r
回车,回到一行最前端。(事实上Enter=\r\n
,不过C++中\n
就是\r\n
)- 其他详见我的博客 【C++ 程序】 解线性方程组(Cramer法则)。
ALL RIGHTS RESERVED © 2020 Teddy van Jerry
欢迎转载,转载请注明出处。