我需要确定一个简单表达式的LHS是否等于其RHS。输入包含整数N,然后是N行表达式。无论表达式是否正确,输出还包含N行(输出CORRECT
或WRONG
)。
所以我试图为N行输入编写for循环,用于(int i = 1; i <= n; ++ i),但是我不知道在for循环中还包括什么。>
还如何验证方程的LHS是否等于RHS?
答案 0 :(得分:0)
您可以这样做:
答案 1 :(得分:0)
对于这样的输入(假设将其保存在文件“ equation_list.txt”中):
3
3 = 1 + 2
3 = 3 + 2
3 * 9 = 26 + 1
以下代码将生成如下控制台输出:
CORRECT
WRONG
CORRECT
函数for (int i = 1; i <= std::stoi(equations[0]); i++)
中的int main()
是您在问题中提到的循环。在循环发生之前,需要进行一些文件和字符串操作。
#include <fstream>
#include <sstream>
#include <vector>
#include <iostream>
#include <limits>
#include "exprtk.hpp"
bool check_equation(const std::string LHS, const std::string RHS)
{
typedef exprtk::expression<double> expression_t;
typedef exprtk::parser<double> parser_t;
expression_t expression;
parser_t parser;
// Calculate LHS's value.
parser.compile(LHS, expression);
double LHS_result = expression.value();
// Calculate RHS's value.
parser.compile(RHS, expression);
double RHS_result = expression.value();
// Check if the difference of these two results is less than a very small
// value EPSILON.
// This is the proper way in C++ to check equation of double values.
// "if (LHS_result == RHS_result)" is not reliable.
if (abs(LHS_result - RHS_result) < std::numeric_limits<double>::epsilon())
{
return true;
}
else
{
return false;
}
}
int main()
{
std::ifstream file("equation_list.txt");
std::stringstream buffer;
// Read the equation list from file, saving into buffer.
if (file)
{
buffer << file.rdbuf();
file.close();
}
else
{
std::cout << "equation file does not exist!";
}
// Split the equations to individual ones (delimiter is '\n' (newline symbol)),
// saving into a vector.
std::vector<std::string> equations;
std::string s;
while (getline(buffer, s, '\n'))
{
equations.push_back(s);
}
// Loop the vector to check the correctness of each equation.
// equations[0] is the number of equations (the first line in input).
for (int i = 1; i <= std::stoi(equations[0]); i++)
{
// Again, using the previous technique, split this equation by
// delimiter '=', saving the result (i.e. LHS and RHS) into a vector.
std::stringstream individual_equation(equations[i]);
std::vector<std::string> parts;
std::string s;
// Assuming each line of equations has one and only one '=' symbol. Checking omitted.
while (getline(individual_equation, s, '='))
{
parts.push_back(s);
}
// Now, parts[0] is LHS, and parts[1] is RHS.
// Check if LHS equals to RHS.
if (check_equation(parts[0], parts[1]) == true)
{
std::cout << "CORRECT" << std::endl;
}
else
{
std::cout << "WRONG" << std::endl;
}
}
return 0;
}
问题的棘手部分是模拟字符串输入(LHS和RHS)的数学计算。这并不像乍看起来那样直观。我建议使用外部库解决此计算问题(请参见代码中的#include "exprtk.hpp"
和函数bool check_equation(const std::string LHS, const std::string RHS)
)。该库称为 ExprTk 。您可以在http://partow.net/programming/exprtk/index.html中找到有关ExprTk的更多信息。
如果您打算自己实现数学计算模拟,建议您先研究一下Polish Notation,这是一种方便于计算机的读取表达式的方式。
仅提供波兰表示法的示例。 a + b / c - d * e
是方便阅读的表达方式。计算机方便的方式是将其功能性地读取为sub(add(a, div(b, c)), mul(d, e))
。将函数名替换为操作数符号后,该名称将变为波兰语表示法-+a/bc*de
。
最后,数据结构Binary Tree在实践中会变得很方便,所有操作数都位于叶子节点上,所有运算符都位于非叶子节点上。