C++:多项式矩阵的输出

C++: Output for Polynomial Matrix

我有一个 std::vector<T> 类型的多项式和一个 std::vector<std::vector<T>> 类型的矩阵,它们都为 类。每个 类 的输出(在我的例子中是 void print()-函数)工作正常。现在我创建了一个由多个多项式组成的矩阵,like this,但我不完全确定如何为其创建输出。

假设我有一个多项式 p1:Polynomial<T> p1{0,1,2}。我的 Polynomial::print 函数正确解释了它并且 returns:x^2+x+1。 对于类型为 Matrix<T> m1(2,2,0) 的 'normal' 矩阵,一个用 0 填充的 2x2 矩阵,可以使用 Matrix::print() 以及:

正确返回
0, 0
0, 0

现在,假设我想要一个多项式矩阵 m1:Matrix<Polynomial<T>> mp(2,2,p1),一个之前的 2x2 矩阵填充多项式 p1。代码被接受,但现在我想使用 matrix::print() 打印矩阵,这样我得到:

x^2+x+1, x^2+x+1
x^2+x+1, x^2+x+1

最小工作示例:

#include<iostream>
#include<vector>

using namespace std;

template <typename T>
class Polynomial;

template <typename T>
class Matrix
{
public:
  Matrix(std::vector<std::vector<T> > ma);
  Matrix(int rows, int cols, T const & init);
  Matrix(const Matrix & m);
  ~Matrix();
  Matrix ();
  void print();
  friend void Polynomial<T>::print();

private:
  std::vector<std::vector<T>> Ma;
};

template <typename T>
Matrix<T>::Matrix(std::vector<std::vector<T>> ma)
  :Ma(ma)
  {}

template <typename T>
Matrix<T>::Matrix(int rows, int cols, T const & init)
{
  std::vector<std::vector<T>> b(rows, std::vector<T>(cols, init));
  Ma=b;
}

template <typename T>
Matrix<T>::~Matrix()
  {}

template <typename T>
Matrix<T>::Matrix() :
Matrix(1,1,0)
{}

template <typename T>
Matrix<T>::Matrix(const Matrix & m)
{
  Ma = m.Ma;
}


template <typename T>
void Matrix<T>::print()
{
  for (auto i = 0; i < Ma.size(); i++)
  {
    for (auto j = 0; j < Ma[i].size(); j++)
      if ( j == Ma.size()-1 )
      {
    cout << Ma[i][j]; //This causes problems
      }
      else
    cout << Ma[i][j] << ", \t";
    cout << endl;
  }
}

template <typename T>
class Polynomial
{
    public:
    Polynomial(std::vector<T> const& coef);
    Polynomial(std::initializer_list<T> const& coef);
    void print();
    const int getdeg();
    const T getKoeff(int index) const;

    friend class Matrix<T>;
    Polynomial ();

    friend void print();

    private:
    std::vector<T> coefficient;

};

template <typename T>
Polynomial<T>::Polynomial(std::vector<T> const& coef) :
    coefficient(coef)
{}

template <typename T>
Polynomial<T>::Polynomial(std::initializer_list<T> const& coef) :
    coefficient(coef)
{}

template <typename T>
Polynomial<T>::Polynomial ()
{
  coefficient = new std::vector<T> [coefficient.getdeg()];
  coefficient[0]=0;
}

template <typename T>
void Polynomial<T>::print() //Reduced version for demonstration purposes, but
{
    for ( int i = getdeg(); i >= 0; i-- )
    {
        cout << coefficient[i] << "x^" << i; //the output is always  of the type cout << xyz
    }
}

template <typename T>
const int Polynomial<T>::getdeg()
{
  int g = coefficient.size()-1;
    return g;
}

int main()
{

 typedef double T;    
  Polynomial<T> p1{0,1,2};
  p1.print();

  Matrix<Polynomial<T>> mp(2, 3, Polynomial<T>{0});
//  mp.print(); //When this is commented out chaos ensues
  return 0;
}
返回

2x^21x^10(注意:+&- 不包括在符号中,因为代码太长)。

matrix::print() 可能会导致问题,因为 cout 在处理多项式的结果时遇到问题。 有人知道如何使 matrix::print() 为多项式矩阵提供有用的结果吗?提前谢谢你。

Matrix<T>::print() 您正在尝试调用

cout << Ma[i][j];

并且当 Ma[i][j]Polynomial<double> 时,输出运算符没有匹配的重载。您可以改为调用 Ma[i][j].print(),但是您的 Matrix 将无法为 int 工作。 Long story short:与其编写自己的 print(),不如为您的类型重载 operator<<(std::ostream&,const T&)

对于 Polynomial,这将是类似的东西(我允许自己将您的代码剥离很多并添加“+”):

#include<iostream>
#include<vector>

template <typename T> struct Polynomial { std::vector<T> data; };

template <typename T> 
std::ostream& operator<<(std::ostream& o,const Polynomial<T>& pol) {        
    auto power = [](int n){ 
        return (n==0) ? "" : (n==1) ? "x" : "x^" + std::to_string(n);
    };
    auto sign = [&](int i){ 
        return (pol.data[i]<0 || i==pol.data.size()-1) ? "" : "+";
    }; 
    // DO THIS ONLY AT HOME !!!  --------v        
    for (size_t i = pol.data.size()-1; i < pol.data.size(); i-- ) {
        o << sign(i) << pol.data[i] << power(i); 
    }
    return o;
}

int main() {
    Polynomial<double> p1{{0,1,2,-3,4}};
    std::cout << p1 << "\n";
}

版画

4x^4-3x^3+2x^2+1x+0

你不需要写 desctructors/constructors 编译器可以为你写。实际上它不需要任何构造函数,只要 at 只是一个伪装的 std::vector 即可。请注意,我试图保持简短,但不一定干净,例如我永远不会依赖 unsigned overflow for a loop condition in any serious code, and heavy use of the ternary doesnt really boost readability. However, I am serious about using lambdas。它们有助于将内容本地化。如果最后一个系数是 0 ;).

,我会留给你打印任何内容

要打印矩阵的行,您可以为 std::vector<T> 提供重载,类似于:

template <typename T> struct Matrix {
      using element_type = T;
      using row_type = std::vector<element_type> ;
      using data_type = std::vector<row_type> ;
      Matrix(int rows, int cols, T const & init) : 
          data(data_type(rows,row_type(cols,init)))
      {}
      data_type data;
};

template <typename T> 
std::ostream& operator<<(std::ostream& o,const std::vector<T>& v) {
    for (auto& x : v) o << x << "\t";
    return o;
}

template <typename T> 
std::ostream& operator<<(std::ostream& o,const Matrix<T>& mat) {
    for (const auto& row : mat.data) o << row << "\n";
    return o;
}

现在打印矩阵就这么简单

int main() { 
    using Matrix = Matrix<Polynomial<double>>;
    Polynomial<double> p1{{1,2}};
    Matrix mp(2,3,p1);
    std::cout << mp;
    return 0;
}

版画

2x+1 2x+1 2x+1
2x+1 2x+1 2x+1

另见此处:https://ideone.com/n00bqn (ideone是想取笑我还是什么?:)

您想使用 operator<< 打印 Map[i][j](它是 Polynomial<double>)的内容,但未定义以 Polynomial<double> 作为参数的运算符。所以你应该添加声明

template<class U>
friend std::ostream& operator<<(std::ostream&,const Polynomial<U>&);

在您的 Polynomial 模板中并在 class 之外定义为

template<class T>
std::ostream& operator<<(std::ostream& out, const Polynomial<T>& poly)
{
  poly.print();
  return out;
}

那你可以打电话给

cout << Ma[i][j] << ", ";

在您的 Matrix<T>::print 方法中。