2. 多項式クラス(2)
デフォルトコンストラクタはなんもしなくてもいいでしょう。
あと、簡単に書けるコンストラクタとしては、単項で1次のもの、
Polynomial::Polynomial(string& a) {
Term t;
t.insert(make_pair(a, 1));
insert(make_pair(t, 1));
}
と、何次でもいいもの、
Polynomial::Polynomial(string& a, int b) {
Term t;
if(b == 0)
return;
t.insert(make_pair(a, b));
insert(make_pair(t, 1));
}
が書けますね。まとめるとデフォルト値を使って、
Polynomial::Polynomial(string& a, int b = 1) {
Term t;
if(b == 0)
return;
t.insert(make_pair(a, b));
insert(make_pair(t, 1));
}
あと、値も暗黙のうちに多項式に変換すると便利なので、
Polynomial::Polynomial(double a) {
Term t;
if(a != 0)
insert(make_pair(t, a));
}
も作っておきましょう。
あ、めんどいので、
typedef map<string,int> Term;
としました。
こういう感じに使います。
Polynomial f, g, h;
f = 3 * Polynomial("x") * Polynomial("y"); //3 * x * y
g = Polynomial("z", 3); //z ^ 3
h = f + g; //3 * x * y + z ^ 3
本当は、
Polynomial f("3 * x * y + z ^ 3");
という感じに使いたいのですが、難しいので後回しです。
入力は難しいので、出力が先です。
出力は例えば、
x2 + 3yz
という多項式があったら、
x * x + 3 * y * z
としたいです。
というのは、これだとそのままプログラムのソースに使えるからです。
素直に項ごとに書き出していきましょう。
係数が負のときと±1のときと最初の項に注意です。
ostream& operator <<(ostream& os, const Polynomial& a) {
Polynomial::const_iterator p;
Term::const_iterator q;
for(p = a.begin(); p != a.end(); ++p) {
bool one = true; //係数が±1か
if(p == a.begin()) {
if(p->second == -1)
os << "-";
else if(p->second != 1) {
os << p->second;
one = false;
}
}
else {
if(p->second == -1)
os << " - ";
else if(p->second == 1)
os << " + ";
else if(p->second > 0) {
os << " + " << p->second;
one = false;
}
else {
os << " - " << -p->second;
one = false;
}
}
for(q = p->first.begin(); q != p->first.end(); ++q) {
for(int i = 0; i < p->first->second; i++) {
if(q == p->first.begin() && i == 0 && one)
os << p->first->first;
else
os << " * " << p->first->first;
}
}
}
return os;
}
多項式があったとして、例えばxの項でまとめたいときってやりますよね。
x3 + y3 + z3 + x2y + y2z + z2x + xyz
-> x3 + (y + z)x2 + (y2 + yz + z2)x + (y3 + z3)
こういうときのためにgetTermsメソッドを作っておきます。
map<int,Polynomial> Polynomial::getTerms(const string& a) const {
map<int,Polynomial> result;
Polynomial::const_iterator p;
Term::const_iterator q;
for(p = this->begin(); p != this->end(); ++p) {
Polynomial poly;
if((q = p->first.find(a)) != p->first.end()) {
Term t = p->first;
t.erase(a);
poly.insert(make_pair(t, p->second));
result[q->second] += poly;
}
else {
poly.insert(make_pair(p->first, p->second));
result[0] += poly;
}
}
return result;
}
例えば、引数がxを表す多項式として、帰ってきた値をaとすると、
a[0]がxを含まない項、a[1]がxの項、a[2]がx
2の項、、、となります。
先ほどの例だと、
0 -> y3 + z3
1 -> y2 + yz + z2
2 -> y + z
3 -> 1
となります。
以上により作成されたPolynomialクラスは次のヘッダファイルです。
polynomial.h
次回はこれを使って当初の目的を達成します。