【问题标题】:C++: Output for Polynomial MatrixC++:多项式矩阵的输出
【发布时间】:2018-02-22 17:11:26
【问题描述】:

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

假设我有一个多项式 p1:Polynomial<T> p1{0,1,2}。我的多项式::print 函数正确解释并返回:x^2+x+1。 对于Matrix<T> m1(2,2,0) 类型的“普通”矩阵,一个用 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() 为多项式矩阵提供有用的结果吗?提前谢谢你。

【问题讨论】:

    标签: c++ matrix cout


    【解决方案1】:

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

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

    在您的 Polynomial 模板中,并将类外定义为

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

    那你就可以打电话了

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

    在您的 Matrix&lt;T&gt;::print 方法中。

    【讨论】:

    • 谢谢伙计。但是在调用 Matrix::print() 时似乎仍然存在问题:“在 'std::ostream& operator&) [with T = double; std::ostream = std::basic_ostream]': 需要来自 'void Matrix::print() [with T = Polynom]'
    • @Retze 哦,我的错误,在operator&lt;&lt;() Polynomial 中是用const 限定符声明的,所以有两种解决方案:在Polynomial 类中将const 添加到print 方法(对于 const 对象,您只能调用 const 方法)或者从 operator operator&lt;&lt;(std::ostream&amp; out, Polynomial&lt;T&gt;&amp; poly) 中删除 const。请记住,从print 方法中您调用的是getdeg,所以如果print 是const,getdeg 也应该是const。
    【解决方案2】:

    Matrix&lt;T&gt;::print() 你正在尝试调用

    cout << Ma[i][j];
    

    Ma[i][j]Polynomial&lt;double&gt; 时,输出运算符没有匹配的重载。您可以改为致电Ma[i][j].print(),但您的Matrix 将不适用于intLong story short:与其编写自己的print(),不如为您的类型重载operator&lt;&lt;(std::ostream&amp;,const T&amp;)

    对于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

    您不需要编写编译器可以为您编写的析构函数/构造函数。实际上它不需要任何构造函数,只要只是变相的std::vector。请注意,我试图保持简短,但不一定干净,例如,我永远不会依赖 unsigned overflow 在任何严肃的代码中作为循环条件,并且大量使用 ternary 并不能真正提高可读性。但是,我对使用lambdas 是认真的。它们有助于使内容保持本地化。如果最后一个系数是0,我会留给你不打印任何内容;)。

    要打印矩阵的行,您可以为std::vector&lt;T&gt; 提供重载,这将类似于:

    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是想取笑我还是什么?:)

    【讨论】:

    • 哇,伙计,这就是我所说的优雅方法,而且效果一样好。感谢您的意见。
    • @Retze 请带上一粒盐(或者更确切地说是一袋盐;)。例如,只有在写完答案后,我才意识到打印operator&lt;&lt;(ostream,Matrix) 中的行而不是为vector&lt;T&gt; 提供operator&lt;&lt; 会更好。我希望您不要简单地复制/粘贴它,而是根据您的需要进行调整。有什么不清楚的请追问
    猜你喜欢
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多