我实际上已经开始学习c ++了,如果有人能帮助我完成我的第一步,我将非常感激。 我必须在c ++中制作代数方程式简化器。例如这个等式: X + 5 + 6 + 3Y + 3 + 2Y 应该看起来像这样: X + 5Y + 14 没有划分,但程序应该使用+, - 和*。 我知道这对你们大多数人来说都很容易,但我会陷入困境,如果有人能告诉我应该如何开始,我会很高兴:/
提前谢谢你, 答案:)
答案 0 :(得分:5)
首先,准确定义您需要使用的数学类型。这些是多项式,而不是代数方程。更容易简化。
接下来,选择一个数据结构来表示多项式。多项式是一个项的和,每个项都有一个系数,一组变量带有指数。在这种情况下,所有系数和指数都是整数。并且,让我们假设这些整数将落在正负十亿之内。
我们已经可以定义一些类了。
#include <vector>
#include <cstdint>
typedef std::int32_t value;
struct power {
char variable;
value degree;
};
struct monomial {
value coefficient;
std::vector< power > product;
};
struct polynomial {
std::vector< monomial > sum;
};
接下来,在给定文本格式的类上定义输入和输出。
#include <iostream>
std::istream & operator >> ( std::istream & is, power & obj ) {
// Skip leading space.
std::istream::sentry s( is );
// Read one character for the variable name.
// Require that it be a letter.
if ( is && std::isalpha( is.peek() ) ) {
is >> obj.variable;
} else {
// Otherwise, the input is invalid.
is.clear( std::ios::failbit );
}
// Read the exponent if its presence is indicated by a ^.
if ( is ) {
if ( is.peek() == '^' ) {
is.ignore();
is >> obj.degree;
} else {
obj.degree = 1;
is.clear();
}
}
return is;
}
std::ostream & operator << ( std::ostream & os, power const & obj ) {
os << obj.variable;
if ( obj.degree != 1 ) {
os << '^' << obj.degree;
}
return os;
}
std::istream & operator >> ( std::istream & is, monomial & obj ) {
obj.coefficient = 1;
obj.product.clear();
// Read a sequence of numbers and exponentiated variables,
// optionally separated by * .
bool did_read_asterisk = false;
do {
// Try reading a coefficient. (And ignore leading space.)
value coefficient;
if ( is >> coefficient ) {
obj.coefficient *= coefficient;
} else if ( is.rdstate() & std::ios::failbit ) {
// If it was absent, tell iostream to resume input.
is.clear( is.rdstate() & ~ std::ios::failbit );
// Read a power instead.
power p;
if ( is >> p ) {
obj.product.push_back( p );
}
// It's OK if the power was missing too, unless there was a * .
if ( ! did_read_asterisk && ( is.rdstate() & std::ios::failbit ) ) {
is.clear( is.rdstate() & ~ std::ios::failbit );
return is;
}
}
did_read_asterisk = false;
// Skip trailing space.
if ( is >> std::ws ) {
if ( is.eof() ) {
// Succeed if this is the end of input.
return is;
}
if ( is.peek() == '*' ) {
is.ignore();
did_read_asterisk = true;
}
if ( is.peek() == '+' || is.peek() == '-' ) {
break;
}
}
} while ( is );
return is;
}
std::ostream & operator << ( std::ostream & os, monomial const & obj ) {
if ( obj.coefficient != 1 || obj.product.empty() ) {
os << obj.coefficient;
}
for ( power const & p : obj.product ) {
os << p;
}
return os;
}
std::istream & operator >> ( std::istream & is, polynomial & obj ) {
// Skip leading space and reject EOF.
std::istream::sentry s( is );
// If there is no minus sign, start positive.
bool positive = true;
if ( is && is.peek() == '-' ) {
is.ignore();
positive = false;
}
// Read a sequence of monomials separated by + or - signs.
monomial m;
while ( is >> m ) {
if ( ! positive ) m.coefficient = - m.coefficient;
obj.sum.push_back( m );
is >> std::ws;
char next_op = is.peek();
if ( is && ( next_op == '+' || next_op == '-' ) ) {
is.ignore();
positive = next_op == '+';
} else if ( ! is.bad() ) {
// Succeed if the next operator is missing.
is.clear();
return is;
}
}
return is;
}
std::ostream & operator << ( std::ostream & os, polynomial const & obj ) {
bool skip_leading_plus = true;
for ( monomial const & m : obj.sum ) {
if ( m.coefficient > 0 && ! skip_leading_plus ) {
os << '+';
}
os << m;
skip_leading_plus = false;
}
return os;
}
接下来,编写简化逻辑。
#include <algorithm>
struct variable_order {
bool operator() ( power lhs, power rhs ) {
return lhs.variable < rhs.variable;
}
};
struct variable_same {
bool operator() ( power lhs, power rhs ) {
return lhs.variable == rhs.variable;
}
};
monomial simplify( monomial in ) {
std::sort( in.product.begin(), in.product.end(), variable_order{} );
for ( auto it = in.product.begin();
( it = std::adjacent_find( it, in.product.end(), variable_same{} ) )
!= in.product.end(); ) {
value degree = it->degree;
it = in.product.erase( it );
it->degree += degree;
}
in.product.erase( std::remove_if( in.product.begin(), in.product.end(),
[]( power p ) { return p.degree == 0; } ), in.product.end() );
return in;
}
struct power_order {
bool operator() ( power lhs, power rhs ) {
return lhs.variable < rhs.variable? true
: lhs.variable > rhs.variable? false
: lhs.degree < rhs.degree;
}
};
struct power_same {
bool operator() ( power lhs, power rhs ) {
return lhs.variable == rhs.variable
&& lhs.degree == rhs.degree;
}
};
struct product_order {
bool operator() ( monomial lhs, monomial rhs ) {
return std::lexicographical_compare( lhs.product.begin(), lhs.product.end(),
rhs.product.begin(), rhs.product.end(),
power_order{} );
}
};
struct product_same {
bool operator() ( monomial lhs, monomial rhs ) {
return std::equal( lhs.product.begin(), lhs.product.end(),
rhs.product.begin(), rhs.product.end(),
power_same{} );
}
};
polynomial simplify( polynomial in ) {
for ( auto & m : in.sum ) {
m = simplify( m );
}
std::sort( in.sum.begin(), in.sum.end(), product_order{} );
for ( auto it = in.sum.begin();
( it = std::adjacent_find( it, in.sum.end(), product_same{} ) )
!= in.sum.end(); ) {
value coefficient = it->coefficient;
it = in.sum.erase( it );
it->coefficient += coefficient;
}
in.sum.erase( std::remove_if( in.sum.begin(), in.sum.end(),
[]( monomial m ) { return m.coefficient == 0; } ), in.sum.end() );
// Represent zero rather than "nothing."
if ( in.sum.empty() ) in = polynomial{{ monomial{ 0, {} } }};
return in;
}
最后,将它们捆绑在一起。
int main() {
polynomial p;
std::cin >> p;
std::cout << simplify( p ) << '\n';
}
看,C ++非常糟糕!
答案 1 :(得分:0)
这实际上是一个非常困难的问题。假设您将数据作为字符串使用,您需要在运算符上拆分字符串以获取2x
或14y
等单个组件。然后,您需要使用某种正则表达式检查表达式中存在哪些变量,并将值转换为您将处于的任何向量空间中的向量。例如,如果您确定将使用的最大变量数为2,向量空间将在R3中。例如,5x
将变为[0,5,0]
,其中第一个元素表示没有变量后缀的数字,第二个元素表示x的数量,第三个元素表示y的数量。最后你应该有大量的向量,你可以将它们相加到一个向量并将其转换回字符串以输出到屏幕。像sympy这样的Python库要求你输入你将要使用的变量,以便它在内部知道它将要计算的向量空间。
我们以您的问题为例。它将接受字符串x+5+6+3y+3+2y
并在加号上拆分并删除额外的空格,给出单独的字符串x
,5
,6
等。然后你会将字符串转换为向量,在这种情况下,它们将是[0,1,0]
,[5,0,0]
,[6,0,0]
,[0,0,3]
...其中第一个元素表示没有变量的数字的数量后缀,第二个元素,如果是x的数量等,那么你将总结所有向量以获得[14,1,5]
的最终向量,然后你将它转换回字符串’14+1x+5y’
,并将其打印到屏幕上。
这是线性代数中的一个概念,称为同构,您可以将一组向量转换为另一个向量空间,因此问题在计算上更容易(或可能)。在你的情况下,你将把P2(二次多项式)中的一组向量转换为R3(实数组中的三度向量),简化表达式,并将R3向量转换回P2以回馈给用户。因为我确定你已经搞清楚了,这个问题可能会更多一点,你已经准备好依赖数学,但这对你来说可能是一个很好的练习。无论如何。
希望这有帮助!