C++ 多项式运算
我正试图编写一个程序,从输入文件构造多项式。它读入多项式并将值存储到类属性“系数”和“指数”中。例如,系数=2,指数=3将导致2x^3。在读入多项式并输出时,有许多恼人的角落情况必须处理。(C++ 多项式运算,c++,class,C++,Class,我正试图编写一个程序,从输入文件构造多项式。它读入多项式并将值存储到类属性“系数”和“指数”中。例如,系数=2,指数=3将导致2x^3。在读入多项式并输出时,有许多恼人的角落情况必须处理。(operator函数)我的主函数彻底测试了我的多项式.cpp。我相信我的一个问题来自于构造多项式,正如你可能注意到的,我也很难为我的派生函数编写代码。以下是我所拥有的: #ifndef _POLYNOMIAL_H #define _POLYNOMIAL_H #include <iostream>
operator
函数)我的主函数彻底测试了我的多项式.cpp。我相信我的一个问题来自于构造多项式,正如你可能注意到的,我也很难为我的派生函数编写代码。以下是我所拥有的:
#ifndef _POLYNOMIAL_H
#define _POLYNOMIAL_H
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
class Polynomial {
public:
Polynomial();
Polynomial(vector<double> iCoefficients, vector<int> iExponents);
int Degree() const;
double Evaluate(double x) const;
Polynomial Derivative() const;
friend Polynomial operator+(const Polynomial & p, const Polynomial & p2);
friend Polynomial operator*(const Polynomial & p, const Polynomial & p2);
friend ostream& operator<<(ostream& out, const Polynomial & p);
friend istream& operator>>(istream& in, Polynomial & p);
private:
vector<double> coefficients;
};
#endif
#include "polynomial.h"
#include <stdexcept>
#include <vector>
#include <cmath>
using namespace std;
// Default Constructor
Polynomial::Polynomial() {
coefficients.push_back(0);
}
// Constructor for a Polynomial
Polynomial::Polynomial(vector<double> iCoefficients, vector<int> iExponents) {
for (int i = 0; i < iExponents[0]; i++) {
coefficients.push_back(0);
}
for (size_t i = 0; i < iExponents.size(); i++) {
coefficients[(Degree() - iExponents[i])] = iCoefficients[i];
}
}
// Returns highest exponent of the polynomial
int Polynomial::Degree() const {
return coefficients.size();
}
// Evaluates the polynomial at a particular point
double Polynomial::Evaluate(double x) const {
double result;
for(int i = 0; i <= Degree(); i++) {
result += pow(x, Degree() - i) * coefficients[i];
}
return result;
}
// Returns first derivative of the polynomial
Polynomial Polynomial::Derivative() const { //----------------------???
// Polynomial result;
// for(int i = 0; i <= Degree(); i++) {
// result.coefficients[i] = coefficients[i] * (Degree() - i);
// }
// return result;
}
// Returns polynomial object that is the sum of parameters
Polynomial operator+(const Polynomial & p, const Polynomial & p2) {
int d = p.Degree();
int d2 = p2.Degree();
Polynomial sum;
for (int j = 0; j < d; j++) {
for (int i = 0; i < d2; i ++) {
sum.coefficients.push_back(p.coefficients[j] + p2.coefficients[i]);
}
}
return sum;
}
// Returns polynomial object that is the product of parameters
Polynomial operator*(const Polynomial & p, const Polynomial & p2) {
int d = p.Degree();
int d2 = p2.Degree();
Polynomial product;
for (int j = 0; j < d; j++) {
for (int i = 0; i < d2; i ++) {
product.coefficients.push_back(p.coefficients[j] * p2.coefficients[i]);
}
}
return product;
}
// Output operator
ostream& operator<<(ostream& out, const Polynomial & p) {
for (int i = 0; i <= p.Degree(); i++) {
if(i == 0 && p.Degree() <= 1) {
out << 0;
}
if (p.coefficients[i] != 0 && i != 0) {
out << '+';
}
if (p.coefficients[i] != 0) {
out << p.coefficients[i];
if(i < (p.Degree() - 1)) {
out << "x^";
out << (i - p.Degree()) * (-1);
}
}
}
return out;
}
// Input operator
istream& operator>>(istream& in, Polynomial & p) {
char ch;
int exponent;
double coefficient;
vector<double> coefficients;
vector<int> exponents;
while(isspace(ch) == false) {
ch = in.peek();
if(ch == '+') {
in.ignore();
in >> coefficient;
}
else if(ch == '-') {
in.ignore();
in >> coefficient;
coefficient = coefficient * (-1);
}
else {
in >> coefficient;
}
ch = in.peek();
if((ch <= 'z') && (ch >= 'a')) {
in >> ch;
ch = in.peek();
if(ch == '^') {
in.ignore();
in >> exponent;
}
else
exponent = 1;
}
else
exponent = 0;
coefficients.push_back(coefficient);
exponents.push_back(exponent);
}
p = Polynomial(coefficients, exponents);
return in;
}
#include <iostream>
#include <sstream>
#include <string>
#include <cmath>
#include "polynomial.h"
using namespace std;
bool testPolynomial(const Polynomial& p, string expected);
bool testOperations(const Polynomial& p, int degree, double expected);
bool testInput(string s);
int main() {
int errors = 0;
cerr << "Note: Nearly all of the tests expect a working output operator. If a test fails, check that first" << endl;
cerr << "Testing default constructor" << endl;
Polynomial p1; // test default constructor
errors += testPolynomial(p1, "0");
cerr << "Testing explicit value constructor" << endl;
double c_arr[] = {1.1, 2, 4, 7};
int e_arr[] = {6, 3, 2, 0};
vector<double> c(c_arr, c_arr+4);
vector<int> e(e_arr, e_arr+4);
Polynomial p2(c, e);
errors += testPolynomial(p2, "1.1x^6+2x^3+4x^2+7");
c.clear(); e.clear();
cout << '1' << endl;
Polynomial p3(c, e);
errors += testPolynomial(p3, "0");
cout << '2' << endl;
cerr << "Testing operations" << endl;
double c2_arr[] = {-1.1, 2, -4, 7};
int e2_arr[] = {4, 3, 2, 0};
vector<double> c2(c2_arr, c2_arr+4);
vector<int> e2(e2_arr, e2_arr+4);
Polynomial p4(c2,e2);
errors += testOperations(p1, 0, 0);
errors += testOperations(p2, 6, 109.4);
errors += testOperations(p4, 4, -10.6);
errors += testPolynomial(p1.Derivative(), "0");
errors += testPolynomial(p2.Derivative(), "6.6x^5+6x^2+8x");
errors += testPolynomial(p4.Derivative(), "-4.4x^3+6x^2-8x");
errors += testPolynomial(p1+p2, "1.1x^6+2x^3+4x^2+7");
errors += testPolynomial(p2+p4, "1.1x^6-1.1x^4+4x^3+14");
errors += testPolynomial(p1*p2, "0");
errors += testPolynomial(p2*p2, "1.21x^12+4.4x^9+8.8x^8+19.4x^6+16x^5+16x^4+28x^3+56x^2+49");
double c_arr3[] = {-1};
int e_arr3[] = {0};
vector<double> c3 = vector<double>(c_arr3, c_arr3+1);
vector<int> e3 = vector<int>(e_arr3, e_arr3+1);
Polynomial p5(c3, e3);
errors += testPolynomial(p2 * p5 + p2, "0");
errors += testPolynomial(p5, "-1");
cerr << "Testing input operator." << endl;
testInput("0");
testInput("51");
testInput("-1.1");
testInput("3x^2");
testInput("-5x^3-5");
testInput("x^5+x-1");
testInput("-x^4+2");
return errors;
}
bool testPolynomial(const Polynomial& p, string expected) {
ostringstream out;
out << p;
if (out.str() != expected) {
cerr << "Test failed: expected " << expected << " got " << out.str() << endl;
return true;
} else {
return false;
}
}
bool testOperations(const Polynomial& p, int degree, double expected) {
if(p.Degree() != degree) {
cerr << "Failed Degree operation" << endl;
return true;
}
double result = p.Evaluate(2.0);
if (fabs(result - expected) > 1e-5) {
cerr << "Failed Evaluation operation" << endl;
}
return false;
}
bool testInput(string s) {
Polynomial p;
istringstream in(s+" ");
in >> p;
ostringstream out;
out << p;
if (out.str() != s) {
cerr << "Failed input test. Expected: " << s << " got " << out.str() << endl;
return true;
}
return false;
}
\ifndef\u多项式\u H
#定义多项式
#包括
#包括
#包括
使用名称空间std;
类多项式{
公众:
多项式();
多项式(向量i系数、向量i指数);
int度()常数;
双评价(双x)常数;
多项式导数()常数;
友元多项式算子+(常数多项式&p,常数多项式&p2);
友元多项式算子*(常数多项式&p,常数多项式&p2);
friend ostream&operator(istream&in,多项式&p);
私人:
向量系数;
};
#恩迪夫
#包括“多项式.h”
#包括
#包括
#包括
使用名称空间std;
//默认构造函数
多项式::多项式(){
系数。推回(0);
}
//多项式的构造函数
多项式::多项式(向量i系数,向量i指数){
for(int i=0;i指数;
}
其他的
指数=1;
}
其他的
指数=0;
系数。推回(系数);
指数。推回(指数);
}
p=多项式(系数、指数);
返回;
}
#包括
#包括
#包括
#包括
#包括“多项式.h”
使用名称空间std;
布尔测试多项式(常数多项式&p,应为字符串);
布尔测试运算(常数多项式&p,整数次,双期望);
布尔测试输入(字符串s);
int main(){
整数误差=0;
cerrpolymonent::Degree()
函数有一个off by one bug;它应该返回size()-1
为了转换系数和指数列表,首先找到最大指数;这将是多项式的次数:
int degree = *std::max_element(iExponents.begin(), iExponents.end());
然后,用这个数量的零(加上一,见上文)初始化系数:
然后,设置每个系数,就像您所做的那样
但是,最好使用幂/指数的升序!这样,您就不需要一直计算
Degree()-i
,您可以使用i
for (size_t i = 0; i < iExponents.size(); i++) {
coefficients[iExponents[i]] += iCoefficients[i];
}
一旦你试着去想,剩下的应该会更容易
执行加法后,您可能希望检查最高阶系数是否为零;例如,当您添加
2x^2+x+1
和-2x^2+x+1
时,您会得到0x^2+2x+2
,您可能希望将其转换为2x+2
:
while (coefficients.back() == 0)
coefficients.resize(coefficients.size() - 1);
if (coefficients.empty())
coefficients.push_back(0);
一旦你得到了
运算符+
和运算符*
正确,导数应该很容易。那么…你做了什么,你的问题到底是什么?你似乎没有正确地实现和和和积。你能用某种代数符号写下这些运算的数学公式,并与你所拥有的进行比较吗e?在不相关的新闻中,不要将使用名称空间std
放在头文件中。通常,要求两个std::vector
s具有完全相同的长度是一个坏主意。相反,要有一个std::vector
,其中两个数据段都作为对
s(或struct
s)。系数和指数对是多项式中的一个“项”,这可能是结构的一个很好的名称。
。这种抽象的好处是,如果你总是使用术语,那么在上面的代码中犯一些错误就更难了。例如,写“term GetNthTerm(int n)const”和“size\t HowManyTerms()const”,并且您的大部分代码开始更容易正确编写。抱歉,我不清楚。我的显式值构造函数似乎工作不正常。我将看看我的求和和和积函数。有趣的是:似乎您试图允许多项式中变量的任何名称,而不仅仅是x
。而是字母e
很特别:2x+2x^2
可以,但是2e+2e^2
被解析为200e^2
哇,太感谢了!你处理了我所有的问题。我会把我的代码清理干净,应该能够算出加法乘法和导数函数。再次感谢!
Polynomial operator+(const Polynomial & p, const Polynomial & p2)
{
int d = p.Degree();
int d2 = p2.Degree();
Polynomial sum;
sum.coefficients.assign(std::max(d, d2) + 1, 0);
...
}
while (coefficients.back() == 0)
coefficients.resize(coefficients.size() - 1);
if (coefficients.empty())
coefficients.push_back(0);