方程计算器

解方程对于一些小学生极其的不友好,总是会看错算错,另他们十分头疼,而机器就完全不会看错,因此这篇文章是专门给小学生看的(不是小学生的别不好意思看)

下面给大家看一下我的程序

#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
#include <stack>
#include <cctype>
#include <iomanip> // 用于输出格式控制

using namespace std;

// 函数:将整数转换为字符串
string int_to_string(int num) {
    stringstream ss;
    ss << num;
    return ss.str();
}

// 函数:将浮点数转换为字符串(去掉多余的零)
string double_to_string(double num) {
    stringstream ss;
    ss << fixed << setprecision(3) << num; // 设置输出精度为三位小数
    string str = ss.str();
    
    // 去掉尾部多余的零和可能的小数点
    size_t found = str.find_last_not_of('0');
    if (found != string::npos) {
        if (str[found] == '.') {
            str.erase(found);
        } else {
            str.erase(found + 1);
        }
    }
    
    return str;
}

// 函数:判断运算符的优先级
int precedence(char op) {
    if (op == '+' || op == '-')
        return 1;
    if (op == '*' || op == '/')
        return 2;
    return 0;
}

// 函数:执行操作符运算
double applyOperation(double a, double b, char op) {
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
        default: return 0.0; // 不应该发生
    }
}

// 函数:计算带有括号的表达式的值
double evaluateExpression(string expression, double x) {
    stack<double> values;       // 用于存放操作数
    stack<char> operators;      // 用于存放运算符

    for (size_t i = 0; i < expression.length(); ++i) {
        if (expression[i] == ' ') {
            continue;
        } else if (isdigit(expression[i])) {
            double num = 0;
            while (i < expression.length() && (isdigit(expression[i]) || expression[i] == '.')) {
                num = num * 10 + (expression[i] - '0');
                i++;
            }
            if (i < expression.length() && expression[i] == '.') {
                double fraction = 0.1;
                i++;
                while (i < expression.length() && isdigit(expression[i])) {
                    num += (expression[i] - '0') * fraction;
                    fraction /= 10;
                    i++;
                }
            }
            i--; // 因为循环末尾会再次递增 i
            values.push(num);
        } else if (expression[i] == 'x') {
            values.push(x);
        } else if (expression[i] == '(') {
            operators.push(expression[i]);
        } else if (expression[i] == ')') {
            while (!operators.empty() && operators.top() != '(') {
                char op = operators.top();
                operators.pop();
                double val2 = values.top();
                values.pop();
                double val1 = values.top();
                values.pop();
                values.push(applyOperation(val1, val2, op));
            }
            if (!operators.empty())
                operators.pop(); // 弹出 '('
        } else { // 是运算符 + - * /
            while (!operators.empty() && precedence(operators.top()) >= precedence(expression[i])) {
                char op = operators.top();
                operators.pop();
                double val2 = values.top();
                values.pop();
                double val1 = values.top();
                values.pop();
                values.push(applyOperation(val1, val2, op));
            }
            operators.push(expression[i]);
        }
    }

    // 处理栈中剩余的运算符和操作数
    while (!operators.empty()) {
        char op = operators.top();
        operators.pop();
        double val2 = values.top();
        values.pop();
        double val1 = values.top();
        values.pop();
        values.push(applyOperation(val1, val2, op));
    }

    // 返回最终的计算结果
    return values.top();
}

// 函数:解析方程并计算结果
void solveEquation(string equation) {
    size_t pos = equation.find('=');
    if (pos == string::npos) {
        cout << "输入格式错误!" << endl;
        return;
    }

    // 提取等号左右两边的表达式
    string leftExpression = equation.substr(0, pos);
    string rightExpression = equation.substr(pos + 1);

    // 尝试从 0.000 到 1000.000 的每个值代入 x,并比较左右表达式的值
    bool foundSolution = false;
    for (double x = 0.000; x <= 1000.000; x += 0.001) {
        double leftValue = evaluateExpression(leftExpression, x);
        double rightValue = evaluateExpression(rightExpression, x);
        if (fabs(leftValue - rightValue) < 1e-6) {
            cout << "未知数x的值是:" << double_to_string(x) << endl;
            foundSolution = true;
            break;
        }
    }

    if (!foundSolution) {
        cout << "没有找到结果" << endl;
    }
}

int main() {
    string equation;
    cout << "请输入等式(例:“3 * x + (2 * (x - 1)) = 5”):";
    getline(cin, equation);

    solveEquation(equation);

    return 0;
}

这段 C++ 程序用于解决形如 3 * x + (2 * (x - 1)) = 5 的简单线性方程。程序首先将方程解析成左边和右边的表达式,然后通过逐步试探的方式找到满足方程的 x 值。

以下是程序的主要功能和实现细节:

主要功能

  1. 输入等式: 用户输入一个形如 3 * x + (2 * (x - 1)) = 5 的等式。

  2. 解析等式: 将等式分为左边和右边两部分。

  3. 求解方程: 通过逐步试探的方式,从 x = 0.000 开始,增加 x 的值,直到 x = 1000.000,每次增加 0.001,并计算左边和右边的值,寻找使得两边值相等的 x

  4. 输出结果: 如果找到满足条件的 x,则输出结果;如果没有找到,则输出未找到结果的提示。

代码详解

int_to_string(int num)

这个函数将一个整数转换为字符串。使用 stringstream 类实现转换。

double_to_string(double num)

这个函数将一个 double 类型的数值转换为字符串,并保留三位小数。如果转换后的字符串末尾有多余的零,会去掉这些零。这个函数的目的是确保输出的数字格式尽量简洁。

precedence(char op)

这个函数返回运算符的优先级。加法和减法的优先级为 1,乘法和除法的优先级为 2。

applyOperation(double a, double b, char op)

这个函数执行两个操作数 ab 之间的运算,运算符由 op 决定。支持加法、减法、乘法和除法。

evaluateExpression(string expression, double x)

这个函数解析并计算一个表达式的值,其中可能包含变量 x。使用两个栈来处理操作数和运算符,通过运算符优先级规则来计算表达式的结果。

solveEquation(string equation)

这个函数处理输入的方程。首先将方程拆分为左边和右边的表达式,然后通过逐步试探 x 的值来找到满足方程的解。如果找到了解,则输出;否则输出未找到结果的提示。

main()

主函数:

  1. 提示用户输入一个等式。
  2. 调用 solveEquation 函数来解决这个等式。

注意事项

  1. 浮点数精度: 使用逐步试探的方法求解方程可能存在精度问题,特别是浮点数比较时,程序使用了一个非常小的阈值 1e-6 来判断是否相等。

  2. 性能: 该程序采用了穷举法逐步试探所有可能的 x 值,这种方法在实际应用中可能比较慢,因为需要计算大量的值。对于更复杂或更精确的需求,可能需要更高效的算法或优化方法。

  3. 错误处理: 如果等式格式不正确,程序会提示“输入格式错误”。

  4. 表达式解析: 表达式解析部分的实现较为基础,可能不支持复杂的表达式或特定的语法。

这个程序适合用来处理简单的线性方程,但在实际应用中,如果需要处理更复杂的方程或更高的精度需求,可能需要更高级的数学库或算法。

效果图:

看懂我程序的人已经开始笑了,我的方法非常的笨,十分的暴力,所以有些方程是没有办法解的。

如果大家有更好的方法记得在评论区告诉我哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值