C ++初学者。我特别需要帮助试图弄清楚我的重载*运算符有什么问题,它应该乘以我生成的Poly类的两个多项式。我的其他重载运算符似乎工作正常。这是最初的问题:
P(x) = 2x4 + 3x3 – 12x2 + x – 19 (4th order polynomial)
or
P(x) = 2x7 + 5x5 – 7x2 + x – 19 (7th order polynomial)
Where the coefficients for the first and second equations can be described by the following array of integers
'Coeff1[ ] = {-19, 1, -12, 3, 2}'
'Coeff2[[ ] = {-19, 1, -7, 0, 0, 5, 0, 2}'
Design and code a polynomial class in C++ that has the following properties:
class Poly{
private:
int order; //order of the polynomial
int *coeff; // pointer to array of coeff on the heap
// size of coeff array predicated on (order + 1)
public:
Poly( ); //default constructor – order=0 & coeff[0] =1
Poly(int Order , int Default = 1) ;// creates Nth order poly
// and inits all coeffs
Poly(int Order, int *Coeff); //creates an Nth polynomial & inits
~Poly( ); // destructor
::::::: // copy constructor
//mutators & accessors
void set( ){// Query user for coefficient values);
void set(int coeff[ ], int size); // input coeffs via external coeff vector
int getOrder( )const; // get order of polynomial
int * get( ); //returns pointer to coeff array
//overloaded operators
Poly operator+( const Poly &rhs); // add two polynomials
Poly operator-( const Poly &rhs); // subt two polynomials
Poly operator*( const int scale); // scale a polynomial
Poly operator*(const Poly &rhs); // mult two polynomials
bool operator==(const Poly &rhs); // equality operator
const int & operator[ ](int I)const; // return the Ith coefficient
int & operator[ ](int I); // return the Ith coefficient
int operator( )(int X); // evaluate P(x) according
Poly & operator=(const Poly & rhs);
friend ostream & operator<<(ostream & Out, const Poly &rhs);
//other member functions
};
Demonstrate the following operations for the following Polynomials:
P1(x) = 2x4 + 3x3 – 12x2 + x – 19 (4th order polynomial)
P2(x) = 2x7 + 7x5 – 6x2 + x – 19 (7th order polynomial)
//display the following results for the polynomials defined above
o P3 = P1 + P2;
o P3 = P2 – P1;
o P3 = P1*10;
o P3 = 10*P1;
o P3 = P1*P2;
o bool flag = (P1==P2);
o P1[3] = P2[5]; // assign the 5th coefficient of P2 to 3rd coefficient of P1
o int Z = P1(int X = 5); // evaluate Polynomial for input X
// suggest using Horner’s method
o The displayed polynomial for P2 should be printed as follows
2X^7 + 7X^5 – 6X^2 + 1X – 1
到目前为止我的代码:
#include <iostream>
#include <cmath>
using namespace std;
class Poly
{
private:
int order;
int *coeff;
public:
Poly();
Poly(int Order, int Default=1);
Poly(int Order, int *Coeff);
Poly(const Poly ©);
~Poly();
void set(); //ask the user for the coefficient values
void set(int *Coeff, int size); //put the coefficient values in a external coeff vector
int getOrder() const; //gets the order of the polynomial
int* get() const; //returns pointer to coeff array
Poly operator +(const Poly &rhs);
Poly operator -(const Poly &rhs);
Poly operator *(const int scale);
Poly operator *(const Poly &rhs);
bool operator ==(const Poly &rhs);
const int & operator [](int access) const;
int & operator [](int access);
int operator ()(int X);
Poly & operator =(const Poly &rhs);
friend ostream & operator <<(ostream &Out, const Poly &rhs);
};
int main() {
int coeff1[] = {-19,1,-12,3,2};
int coeff2[] = {-19,1,-7,0,0,5,0,2};
Poly P1(4,coeff1);
Poly P2(7, coeff2);
Poly P3;
cout << "P1: " << P1 << endl;
cout << "P2: " << P2 << endl;
P3 = P1 * P2;
cout << "P1 * P2: " << P3 << endl;
return 0;
}
Poly::Poly() : order(0)
{
coeff = new int[1];
coeff[0] = 1;
}
Poly::Poly(int Order, int Default) : order(Order)
{
coeff = new int[order+1];
for (int i = 0; i < order+1; i++){
coeff[i] = Default;
}
}
Poly::Poly(int Order, int *Coeff) : order(Order), coeff(Coeff)
{
}
Poly::Poly(const Poly & copy)
{
order = copy.getOrder();
coeff = new int[order+1];
for (int i = 0; i < order+1; i++){
coeff[i] = copy.get()[i];
}
}
Poly::~Poly()
{
//if(coeff){
//delete [] coeff;
//}
}
void Poly::set()
{
cout << "Enter your coefficients:\n";
for (int i = 0; i < order+1; i++){
cin >> coeff[i];
}
}
void Poly::set(int *Coeff, int size)
{
delete [] coeff;
coeff = new int[size];
order = size;
for (int i = 0; i < order+1; i++){
coeff[i] = Coeff[i];
}
}
int Poly::getOrder() const
{
return order;
}
int* Poly::get() const
{
return coeff;
}
Poly Poly::operator +(const Poly &rhs)
{
int length = max(order+1, rhs.getOrder()+1);
int *answer = new int[length];
for (int i = 0; i < length + 1; i++){
answer[i] = coeff[i] + rhs.get()[i];
}
if (order > rhs.getOrder()){
for (int i = order+1 - rhs.getOrder()+1 ; i < order+1; i++){
answer[i] = coeff[i];
}
}
else if (order < rhs.getOrder()){
for (int i = rhs.getOrder()+1 - order+1; i < rhs.getOrder()+1; i++){
answer[i] = rhs.get()[i];
}
}
return Poly(length-1, answer);
}
Poly Poly::operator -(const Poly &rhs)
{
int length = max(order+1, rhs.getOrder()+1);
int *answer = new int[length];
for (int i = 0; i < order+1 && i < rhs.getOrder() + 1; i++){
answer[i] = coeff[i] - rhs.get()[i];
}
if (order > rhs.getOrder()){
for (int i = order+1-rhs.getOrder()+1; i < order+1; i++){
answer[i] = coeff[i];
}
}
else if (order < rhs.getOrder()){
for (int i = rhs.getOrder()+1 - order+1; i < rhs.getOrder()+1; i++){
answer[i] = 0 - rhs.get()[i];
}
}
return Poly(length-1, answer);
}
Poly Poly::operator *(const int scale)
{
int *answer = new int[order+1];
for (int i = 0; i < order+1; i++){
answer[i] = coeff[i] * scale;
}
return Poly(order, answer);
}
Poly Poly::operator *(const Poly &rhs)
{
int *shorter = NULL;
int *longer = NULL;
int s = 0;
int l = 0;
if(order < rhs.getOrder()){
shorter = coeff;
s = order;
longer = rhs.coeff;
l = rhs.order;
} else {
shorter = rhs.coeff;
s = rhs.order;
longer = coeff;
l = order;
}
Poly sum = Poly(l, longer) * shorter[0];
int *prod;
int nl;
for (int i = 1; i <= s; i++){
nl = l + i;
prod = new int[nl + 1];
for(int j = 0; j < i; j++){
prod[j] = 0;
}
for(int k = 0; k <= l; k++){
prod[k+i] = shorter[i] * longer[k];
}
sum = sum + Poly(nl, prod);
}
return sum;
}
bool Poly::operator ==(const Poly &rhs)
{
bool result;
if (order == rhs.order){
result = true;
for(int i = 0; i<order+1; i++){
if (coeff[i] != rhs.get()[i]){
result = false;
}
}
}else result = false;
return result;
}
const int& Poly::operator[](int access) const
{
return coeff[order + 1 - access];
}
int& Poly::operator [](int access)
{
return coeff[order + 1 - access];
}
int Poly::operator ()(int x)
{
int total = 0;
for(int i = 0; i < order + 1; i++){
total += coeff[i] * pow(x, i);
}
return total;
}
Poly &Poly::operator =(const Poly &rhs)
{
order = rhs.getOrder();
coeff = rhs.get();
return *this;
}
ostream& operator <<(ostream & Out, const Poly &rhs)
{
Out << rhs.get()[rhs.getOrder()] << "x^" << rhs.getOrder(); //first
for (int i = rhs.getOrder()-1; i > 0; i--){
if (rhs.get()[i] < 0 || rhs.get()[i] > 1) {
if(rhs.get()[i] > 0){
Out << " + ";
}
Out << rhs.get()[i] << "x^" << i << " ";
}else if (rhs.get()[i] == 1){
Out << "+ x ";
}else if (rhs.get()[i] == 1){
Out << "- x";
}
}
if (rhs.get()[rhs.getOrder() - rhs.getOrder()] > 0) {
Out << " + " << rhs.get()[rhs.getOrder() - rhs.getOrder()]; //last
}else Out << rhs.get()[rhs.getOrder() - rhs.getOrder()]; //last
Out << endl;
return Out;
}
`
这是我目前的输出。我一直得到的答案是正确答案的一半,但我似乎无法得到上半部分。
P1: 2x^4 + 3x^3 -12x^2 + x -19
P2: 2x^7 + 5x^5 -7x^2 + x -19
P1 * P2: -114x^5 + 49x^4 -76x^3 + 362x^2 -38x^1 + 361
感谢任何帮助。谢谢
答案 0 :(得分:4)
首先,停止手动管理内存。将order
和coeff
替换为std::vector<int> values;
。这为size()
捆绑order
,并为您处理内存管理。
如果您还不知道如何使用std::vector
,请了解:这比学习如何编写自己的Poly
课容易得多。
实施Poly * Poly
的下一步是实施Poly& operator*=( Poly const& rhs );
最后一步是friend Poly operator*( Poly lhs, Poly const& rhs ) { return std::move(lhs*=rhs); }
没有理由使用多行,它可以是inline
。
离开operator*=
。
实施*=
的第一步,再次通过operator+(Poly const&, Poly const&)
实施Poly& operator+=(Poly const&)
。由于添加很容易,我会把它留给你。
下一步是标量乘法。实施Poly& operator*=(int)
,并friend Poly operator*(Poly lhs, int x) { return std::move( lhs*=x ); }
和friend Poly operator*(int x, Poly rhs) { return std::move( rhs*= x ); }
。这称为“标量乘法”。
一旦我们有了这些,*=
变得容易。
存储我们初始值的副本。 (Poly init = std::move(*this);
)
创建一个返回值(空)。
对于右侧的每个系数,请执行retval += coeff * init;
return *this = std::move(retval);
这是解决方案的草图。要真正解决它,你需要在每个阶段实施测试。因为我在其他操作方面实现了*=
,所以测试每个操作以确保它们的工作对于具有可调试的*=
是关键。然后你测试*=
,然后测试*
,然后你就完成了。
如果您正在使用兼容的C ++编译器进行编译,那么使用std::vector
的一个好处是您的默认复制,移动,赋值和移动分配操作都是正确的,就像您的默认析构函数一样。寻求使用专门的资源管理类来管理资源,并遵循零规则,您将获得更少的痛苦。
请注意,上述*=
并不比*
更容易编写,但总的来说*=
更容易,所以无论如何你应该养成习惯。
最后,请注意,这会分配比所需更多的内存,并且不是最佳的。但是,很容易弄清楚。在完成上述实现之后,您可以通过多种方式使其更加优化。您可以使用karatsuba乘法,您可以使用表达式模板来避免result += coeff * init;
行上的中间乘法,reserve
中可以result
正确的空间,或者您可以开始使用索引手动
第一步应该是正确的,因为如果你有一个正确的算法,你至少可以用它来测试你更优化(更棘手)的算法。
答案 1 :(得分:2)
您的代码(用于多项式乘法)不包含任何注释,而且相当不透明且难以阅读/理解。所以,我拒绝编译它(精神上)并且只能猜测,但似乎你不知道如何定义多项式的乘法,因为你的乘积多项式被设置为order = min(order(A),order (B))+ 1,正确是顺序(A)+顺序(B)。
我建议你,
1确保在开始编码之前理解多项式乘法
2使用最少的指令和有用的注释(或更好的:有用的变量名称)编写清晰的代码
3通过C ++标准库管理内存(使用std::vector<>
)
4构建代码(编写polynomial& polynomial::operator+=(polynomial const&)
然后通过
friend
)
polynomial operator*(polynomial const&a,polynomial const&b)
{
auto c=a;
c*=b;
return std::move(c);
}
虽然您可能希望改进此特定设计(避免重新分配,但在c*=b
操作中的上述代码中是必需的。)
答案 2 :(得分:1)
我想这个:
sum = sum + Poly(length, prod);
应该是
sum = sum + Poly(length + i - 1, prod);
此外,i
上的循环应停在最短coeff
数组长度。
以下是该功能的修改版本:
Poly Poly::operator *(const Poly &rhs)
{
int *shorter = NULL;
int *longer = NULL;
int s = 0;
int l = 0;
if(order < rhs.order){
shorter = coeff;
s = order;
longer = rhs.coeff;
l = rhs.order;
} else {
shorter = rhs.coeff;
s = rhs.order;
longer = coeff;
l = order;
}
Poly sum = Poly(l, longer) * shorter[0];
int *prod;
int nl;
for (int i = 1; i <= s; i++){
nl = l + i;
prod = new int[nl + 1];
for(int j = 0; j < i; j++){
prod[j] = 0;
}
for(int k = 0; k <= l; k++){
prod[k+i] = shorter[i] * longer[k];
}
sum = sum + Poly(nl, prod);
}
return sum;
}
请注意它是如何基于order
值而不是coeff
数组长度(与我在此答案顶部指出的修复相反)。
如果它不适合你,那么你可能在你没有提供的代码中有其他错误,或者你的算法使用数组长度,所以你可能需要调整以使事情正常工作。
最后,正如在其他答案中所说,您应该使用标准库提供的工具,而不是手动处理数组分配。