//hys专属水印
//方程计算器1.0(目前仅支持1元1次、2元1次方程)
#include <bits/stdc++.h>
using namespace std;
#ifdef _WIN32
#include <windows.h>
void setColor(int color) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}
#define COLOR_RESET 7
#define COLOR_GREEN 10
#define COLOR_RED 12
#define COLOR_YELLOW 14
#define COLOR_CYAN 11
#define COLOR_WHITE 15
#else
#define COLOR_RESET "\033[0m"
#define COLOR_GREEN "\033[1;32m"
#define COLOR_RED "\033[1;31m"
#define COLOR_YELLOW "\033[1;33m"
#define COLOR_CYAN "\033[1;36m"
#define COLOR_WHITE "\033[1;37m"
void setColor(int color) {}
#endif
void printGreen(const string& s) { setColor(COLOR_GREEN); cout << s; setColor(COLOR_RESET); }
void printRed(const string& s) { setColor(COLOR_RED); cout << s; setColor(COLOR_RESET); }
void printCyan(const string& s) { setColor(COLOR_CYAN); cout << s; setColor(COLOR_RESET); }
void printWhite(const string& s) { setColor(COLOR_WHITE); cout << s; setColor(COLOR_RESET); }
// ========== 表达式解析器 ==========
class ExpressionParser {
private:
string expr;
size_t pos;
map<char, double> vars;
double parseAddSub();
double parseMulDiv();
double parseFactor();
void skipSpaces() { while (pos < expr.size() && isspace(expr[pos])) pos++; }
public:
ExpressionParser(const string& s) : expr(s), pos(0) {}
void setVar(char name, double value) { vars[name] = value; }
double eval();
};
double ExpressionParser::eval() { pos = 0; return parseAddSub(); }
double ExpressionParser::parseAddSub() {
double result = parseMulDiv();
while (true) {
skipSpaces();
if (pos >= expr.size()) break;
char op = expr[pos];
if (op == '+' || op == '-') { pos++; double val = parseMulDiv(); result += (op == '+') ? val : -val; }
else break;
}
return result;
}
double ExpressionParser::parseMulDiv() {
double result = parseFactor();
while (true) {
skipSpaces();
if (pos >= expr.size()) break;
char op = expr[pos];
if (op == '*' || op == '/') { pos++; double val = parseFactor(); if (op == '*') result *= val; else { if (fabs(val) < 1e-12) throw runtime_error("除以零"); result /= val; } }
else { if (pos < expr.size() && (isalpha(expr[pos]) || expr[pos] == '(')) { double val = parseFactor(); result *= val; } else break; }
}
return result;
}
double ExpressionParser::parseFactor() {
skipSpaces();
if (pos >= expr.size()) throw runtime_error("表达式意外结束");
char ch = expr[pos];
if (ch == '+' || ch == '-') { pos++; double val = parseFactor(); return (ch == '-') ? -val : val; }
if (ch == '(') { pos++; double val = parseAddSub(); skipSpaces(); if (pos >= expr.size() || expr[pos] != ')') throw runtime_error("括号不匹配"); pos++; return val; }
if (isalpha(ch)) { pos++; if (vars.find(ch) != vars.end()) return vars[ch]; throw runtime_error(string("未知变量: ") + ch); }
if (isdigit(ch) || ch == '.') {
string num;
while (pos < expr.size() && (isdigit(expr[pos]) || expr[pos] == '.')) num += expr[pos++];
if (pos < expr.size() && (expr[pos] == 'e' || expr[pos] == 'E')) {
num += expr[pos++];
if (pos < expr.size() && (expr[pos] == '+' || expr[pos] == '-')) num += expr[pos++];
while (pos < expr.size() && isdigit(expr[pos])) num += expr[pos++];
}
try { return stod(num); } catch (...) { throw runtime_error(string("无效数字: ") + num); }
}
throw runtime_error(string("非法字符: ") + ch);
}
string removeSpaces(const string& s) { string r; for (char c : s) if (!isspace(c)) r += c; return r; }
bool isLinearEquation(const string& eq) {
string s = removeSpaces(eq);
size_t pos = s.find('^');
if (pos != string::npos) {
size_t p = pos + 1;
while (p < s.size() && isspace(s[p])) p++;
if (p < s.size() && s[p] == '1') {
if (p + 1 < s.size() && isdigit(s[p + 1])) return false;
return true;
}
return false;
}
return true;
}
long long gcdll(long long a, long long b) { a = abs(a); b = abs(b); while (b) { long long t = a % b; a = b; b = t; } return a; }
string doubleToFraction(double val) {
const double EPS = 1e-9;
if (fabs(val - round(val)) < EPS) {
long long n = (long long)round(val);
return to_string(n);
}
long long num = (long long)round(val * 1000000);
long long den = 1000000;
long long g = gcdll(num, den);
num /= g; den /= g;
if (den < 0) { num = -num; den = -den; }
if (den == 1) return to_string(num);
return to_string(num) + "/" + to_string(den);
}
vector<char> extractVariables(const string& eq) {
string s = removeSpaces(eq);
vector<char> vars;
set<char> found;
for (char c : s) {
if (isalpha(c) && c != 'e' && c != 'E') {
found.insert(c);
}
}
for (char c : found) vars.push_back(c);
return vars;
}
bool parseEquation(const string& eq, double& a, double& b, double& c, string& errorMsg) {
errorMsg = "";
string s = removeSpaces(eq);
if (!isLinearEquation(s)) { errorMsg = "此方程不是线性方程(包含高次项)"; return false; }
size_t eqPos = s.find('=');
string left, right;
if (eqPos == string::npos) { left = s; right = "0"; }
else { left = s.substr(0, eqPos); right = s.substr(eqPos + 1); }
if (left.empty()) { errorMsg = "方程左边不能为空"; return false; }
vector<char> vars = extractVariables(eq);
if (vars.empty()) {
try {
ExpressionParser p(left);
double f = p.eval();
ExpressionParser rp(right);
double rv = rp.eval();
a = 0; b = 0; c = rv - f;
return true;
} catch (const exception& e) {
errorMsg = string("常数方程解析错误: ") + e.what();
return false;
}
}
char var1 = vars[0];
char var2 = (vars.size() > 1) ? vars[1] : 'y';
double rightVal;
try {
ExpressionParser rightParser(right);
rightParser.setVar(var1, 0.0);
rightParser.setVar(var2, 0.0);
rightVal = rightParser.eval();
}
catch (const exception& e) {
errorMsg = string("右侧表达式解析错误: ") + e.what();
return false;
}
try {
ExpressionParser p00(left);
p00.setVar(var1, 0.0);
p00.setVar(var2, 0.0);
double f00 = p00.eval();
ExpressionParser p10(left);
p10.setVar(var1, 1.0);
p10.setVar(var2, 0.0);
double f10 = p10.eval();
ExpressionParser p01(left);
p01.setVar(var1, 0.0);
p01.setVar(var2, 1.0);
double f01 = p01.eval();
ExpressionParser right10(right);
right10.setVar(var1, 1.0);
right10.setVar(var2, 0.0);
double right10Val = right10.eval();
ExpressionParser right01(right);
right01.setVar(var1, 0.0);
right01.setVar(var2, 1.0);
double right01Val = right01.eval();
a = (f10 - right10Val) - (f00 - rightVal);
b = (f01 - right01Val) - (f00 - rightVal);
c = rightVal - f00;
return true;
}
catch (const exception& e) {
errorMsg = string("表达式解析错误: ") + e.what();
return false;
}
}
void highlightResult(const string& label, const string& value, bool isSuccess = true) {
cout << "\n";
printCyan("╔══════════════════════════════════════════════════════════╗\n");
printCyan("║ ");
printWhite("求解结果");
printCyan(" ║\n");
printCyan("╠══════════════════════════════════════════════════════════╣\n");
printCyan("║ ");
cout << label;
int padding = 56 - label.length() - value.length();
if (padding < 0) padding = 0;
if (isSuccess) {
printGreen(value);
} else {
printRed(value);
}
for (int i = 0; i < padding; i++) cout << " ";
cout << " ║\n";
printCyan("╚══════════════════════════════════════════════════════════╝\n");
setColor(COLOR_RESET);
}
void highlightSimple(const string& msg, bool isSuccess = true) {
cout << "\n";
printCyan("╔══════════════════════════════════════════════════════════╗\n");
printCyan("║ ");
if (isSuccess) {
printGreen(msg);
} else {
printRed(msg);
}
int padding = 56 - msg.length();
if (padding < 0) padding = 0;
for (int i = 0; i < padding; i++) cout << " ";
cout << " ║\n";
printCyan("╚══════════════════════════════════════════════════════════╝\n");
setColor(COLOR_RESET);
}
void solveLinear(const string& eq) {
double a, b, c; string error;
cout << "输入方程: " << eq << "\n";
if (!parseEquation(eq, a, b, c, error)) {
printRed("错误: " + error + "\n");
return;
}
vector<char> vars = extractVariables(eq);
char var = (vars.empty()) ? 'x' : vars[0];
if (fabs(b) > 1e-9 && vars.size() > 1) {
cout << "警告: 此方程包含多个变量 (" << vars[0];
if (vars.size() > 1) cout << ", " << vars[1];
cout << "),将忽略其他变量,仅解 " << var << "。\n";
}
cout << "化简为: " << a << var << " = " << c << "\n";
const double EPS = 1e-12;
if (fabs(a) < EPS) {
if (fabs(c) < EPS) {
highlightSimple("方程有无数解 (0 = 0)", true);
} else {
highlightSimple("方程无解 (0 = " + to_string(c) + ")", false);
}
} else {
double x = c / a;
string result = string(1, var) + " = " + doubleToFraction(x);
highlightResult("解: ", result, true);
cout << " 小数形式: " << setprecision(12) << x << "\n";
}
}
void solveSystem(const string& eq1, const string& eq2) {
double a1, b1, c1, a2, b2, c2; string error;
vector<char> vars1 = extractVariables(eq1);
vector<char> vars2 = extractVariables(eq2);
set<char> allVars;
for (char c : vars1) allVars.insert(c);
for (char c : vars2) allVars.insert(c);
vector<char> varList(allVars.begin(), allVars.end());
if (varList.size() == 0) {
printRed("错误: 方程中没有变量\n");
return;
}
char var1 = varList[0];
char var2 = (varList.size() > 1) ? varList[1] : 'y';
cout << "变量: " << var1;
if (varList.size() > 1) cout << ", " << var2;
cout << "\n";
cout << "方程1: " << eq1 << "\n";
if (!parseEquation(eq1, a1, b1, c1, error)) {
printRed("错误 (方程1): " + error + "\n");
return;
}
cout << "方程2: " << eq2 << "\n";
if (!parseEquation(eq2, a2, b2, c2, error)) {
printRed("错误 (方程2): " + error + "\n");
return;
}
cout << "\n解析结果:\n";
cout << " 方程1: " << a1 << var1 << " + " << b1 << var2 << " = " << c1 << "\n";
cout << " 方程2: " << a2 << var1 << " + " << b2 << var2 << " = " << c2 << "\n";
const double EPS = 1e-12;
double D = a1 * b2 - a2 * b1, Dx = c1 * b2 - c2 * b1, Dy = a1 * c2 - a2 * c1;
bool const1 = (fabs(a1) < EPS && fabs(b1) < EPS), const2 = (fabs(a2) < EPS && fabs(b2) < EPS);
if (const1 && const2) {
if (fabs(c1 - c2) < EPS) {
highlightSimple("方程组有无数解 (两个常数方程相同)", true);
} else {
highlightSimple("方程组无解 (两个常数方程矛盾)", false);
}
return;
}
if (const1) {
if (fabs(c1) > EPS) {
highlightSimple("方程组无解 (方程1矛盾: 0 = " + to_string(c1) + ")", false);
return;
}
if (fabs(a2) < EPS && fabs(b2) < EPS) {
if (fabs(c2) < EPS) {
highlightSimple("方程组有无数解", true);
} else {
highlightSimple("方程组无解", false);
}
return;
}
if (fabs(a2) < EPS) {
double y = c2 / b2;
string result = string(1, var1) + " 任意, " + string(1, var2) + " = " + doubleToFraction(y);
highlightResult("解: ", result, true);
cout << " 小数形式: " << setprecision(12) << y << "\n";
}
else if (fabs(b2) < EPS) {
double x = c2 / a2;
string result = string(1, var1) + " = " + doubleToFraction(x) + ", " + string(1, var2) + " 任意";
highlightResult("解: ", result, true);
cout << " 小数形式: " << setprecision(12) << x << "\n";
}
else {
string msg = "方程组有无数解 (一个方程约束)\n 关系: " + to_string(a2) + string(1, var1) + " + " + to_string(b2) + string(1, var2) + " = " + to_string(c2);
highlightSimple(msg, true);
}
return;
}
if (const2) {
if (fabs(c2) > EPS) {
highlightSimple("方程组无解 (方程2矛盾: 0 = " + to_string(c2) + ")", false);
return;
}
if (fabs(a1) < EPS && fabs(b1) < EPS) {
if (fabs(c1) < EPS) {
highlightSimple("方程组有无数解", true);
} else {
highlightSimple("方程组无解", false);
}
return;
}
if (fabs(a1) < EPS) {
double y = c1 / b1;
string result = string(1, var1) + " 任意, " + string(1, var2) + " = " + doubleToFraction(y);
highlightResult("解: ", result, true);
cout << " 小数形式: " << setprecision(12) << y << "\n";
}
else if (fabs(b1) < EPS) {
double x = c1 / a1;
string result = string(1, var1) + " = " + doubleToFraction(x) + ", " + string(1, var2) + " 任意";
highlightResult("解: ", result, true);
cout << " 小数形式: " << setprecision(12) << x << "\n";
}
else {
string msg = "方程组有无数解 (一个方程约束)\n 关系: " + to_string(a1) + string(1, var1) + " + " + to_string(b1) + string(1, var2) + " = " + to_string(c1);
highlightSimple(msg, true);
}
return;
}
if (fabs(D) < EPS) {
if (fabs(Dx) < EPS && fabs(Dy) < EPS) {
bool proportional = true;
if (fabs(a1) > EPS && fabs(a2) > EPS) {
double ratio = a1 / a2;
if (fabs(b1 - b2 * ratio) > EPS * 100 || fabs(c1 - c2 * ratio) > EPS * 100) proportional = false;
}
else if (fabs(b1) > EPS && fabs(b2) > EPS) {
double ratio = b1 / b2;
if (fabs(a1 - a2 * ratio) > EPS * 100 || fabs(c1 - c2 * ratio) > EPS * 100) proportional = false;
}
else proportional = true;
if (proportional) {
string msg = "方程组有无数解 (两个方程成比例)\n 关系: " + to_string(a1) + string(1, var1) + " + " + to_string(b1) + string(1, var2) + " = " + to_string(c1);
highlightSimple(msg, true);
} else {
highlightSimple("方程组有无数解 (方程线性相关)", true);
}
} else {
highlightSimple("方程组无解 (矛盾)", false);
}
} else {
double x = Dx / D, y = Dy / D;
string result = string(1, var1) + " = " + doubleToFraction(x) + ", " +
string(1, var2) + " = " + doubleToFraction(y);
highlightResult("解: ", result, true);
cout << " 小数形式: " << var1 << " = " << setprecision(12) << x << ", " << var2 << " = " << setprecision(12) << y << "\n";
double v1 = a1 * x + b1 * y, v2 = a2 * x + b2 * y;
cout << "验证: " << v1 << " = " << c1 << ", " << v2 << " = " << c2 << "\n";
}
}
int main() {
int choice; string eq1, eq2;
#ifdef _WIN32
system("color 0F");
#endif
cout << "==============================================\n";
printCyan(" 方程求解器 (支持任意变量 + 高亮结果)\n");
cout << "==============================================\n";
cout << "支持格式:\n";
cout << " - 一元: 2a+3=7, 3*t-5=10, -z+4=2z+1\n";
cout << " - 二元: 2a+3b=5, m-2n=1, 3x-4y+2=0\n";
cout << " - 右边有变量: 78+91=x, 2x+3=5x-7\n";
cout << " - 隐式乘法: 2x, 3(x+1), (x+1)(x+2)\n";
cout << " - 负数: -x+2=3, 2a-3b=-5\n";
cout << "==============================================\n";
while (true) {
cout << "\n请选择:\n";
cout << " 1. 解一元一次方程\n";
cout << " 2. 解二元一次方程组\n";
cout << " 3. 退出\n";
cout << "选择 (1/2/3): ";
cin >> choice;
if (cin.fail()) { cin.clear(); cin.ignore(10000, '\n'); cout << "输入无效,请输入数字 1, 2 或 3。\n"; continue; }
cin.ignore(10000, '\n');
switch (choice) {
case 1:
cout << "请输入一元一次方程: ";
getline(cin, eq1);
if (eq1.empty()) cout << "方程不能为空。\n";
else solveLinear(eq1);
break;
case 2:
cout << "请输入第一个方程: ";
getline(cin, eq1);
if (eq1.empty()) { cout << "方程不能为空。\n"; break; }
cout << "请输入第二个方程: ";
getline(cin, eq2);
if (eq2.empty()) { cout << "方程不能为空。\n"; break; }
solveSystem(eq1, eq2);
break;
case 3:
cout << "感谢使用,再见!\n";
return 0;
default:
cout << "无效选择,请输入 1, 2 或 3。\n";
}
}
return 0;
}