225 lines
3.8 KiB
C++
225 lines
3.8 KiB
C++
#include "polynomial.h"
|
||
Polynomial::Polynomial()
|
||
{
|
||
mono.clear();
|
||
leader_order = -1;
|
||
degree = -1;
|
||
}
|
||
bool Polynomial::input(istream& in)
|
||
{
|
||
int state = 0; //0:记录,1:记录变量编号,2:忽略,3:零单项式
|
||
char vari[D] = { 0 };
|
||
int vari_place = 0;
|
||
int now_vari = 0;
|
||
Monomial m;
|
||
bool first = true;
|
||
while (1)
|
||
{
|
||
char c;
|
||
in.get(c);
|
||
if (c == 'x')
|
||
{
|
||
state = 1;
|
||
first = false;
|
||
}
|
||
else if (c >= '0' && c <= '9')
|
||
{
|
||
if (state == 0) //单独的数字:奇数不做处理,偶数将该单项式置为零单项式
|
||
{
|
||
if (c % 2 == 0)
|
||
state = 3;
|
||
else
|
||
state = 4;
|
||
}
|
||
if (state == 1)
|
||
{
|
||
now_vari *= 10;
|
||
now_vari += c - '0';
|
||
}
|
||
first = false;
|
||
}
|
||
else if (c == '*')
|
||
{
|
||
state = 0;
|
||
vari[vari_place++] = now_vari;
|
||
now_vari = 0;
|
||
}
|
||
else if (c == '+')
|
||
{
|
||
if (state == 4)
|
||
{
|
||
m.from_factor(vari, vari_place);
|
||
mono.add(m.order);
|
||
}
|
||
else if (state != 3)
|
||
{
|
||
vari[vari_place++] = now_vari;
|
||
m.from_factor(vari, vari_place);
|
||
mono.add(m.order);
|
||
}
|
||
state = 0;
|
||
now_vari = 0;
|
||
vari_place = 0;
|
||
}
|
||
else if (c == '^')
|
||
{
|
||
state = 2;
|
||
}
|
||
else if (c == ' '); //不进行任何操作
|
||
else if (c == '\n' || c == '\r')
|
||
{
|
||
if (!first)
|
||
{
|
||
if (state == 4)
|
||
{
|
||
m.from_factor(vari, vari_place);
|
||
mono.add(m.order);
|
||
}
|
||
else if (state != 3)
|
||
{
|
||
vari[vari_place++] = now_vari;
|
||
m.from_factor(vari, vari_place);
|
||
mono.add(m.order);
|
||
}
|
||
state = 0;
|
||
now_vari = 0;
|
||
vari_place = 0;
|
||
}
|
||
else
|
||
{
|
||
state = 0;
|
||
now_vari = 0;
|
||
vari_place = 0;
|
||
}
|
||
break;
|
||
}
|
||
else
|
||
break;
|
||
|
||
}
|
||
set_leader_degree();
|
||
return !first;
|
||
}
|
||
|
||
void Polynomial::input_order(istream& in)
|
||
{
|
||
int max = -1;
|
||
while (!in.eof())
|
||
{
|
||
int temp = 0;
|
||
in >> temp;
|
||
if (temp != -1)
|
||
{
|
||
mono.set(temp);
|
||
if (max < temp)
|
||
max = temp;
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
leader_order = max;
|
||
}
|
||
|
||
void Polynomial::print(ostream& out)
|
||
{
|
||
Monomial m;
|
||
bool first = true;
|
||
for (int i = M - 1; i >= 0; i--)
|
||
{
|
||
if (mono.get(i))
|
||
{
|
||
m.from_order(i);
|
||
if (!first)
|
||
out << '+';
|
||
else
|
||
first = false;
|
||
m.print(out);
|
||
}
|
||
}
|
||
out << endl;
|
||
}
|
||
|
||
void Polynomial::print_order(ostream& out)
|
||
{
|
||
for (int i = M - 1; i >= 0; i--)
|
||
{
|
||
if (mono.get(i))
|
||
out << setw(4) << i;
|
||
}
|
||
out << endl;
|
||
}
|
||
|
||
bool Polynomial::get(int n)
|
||
{
|
||
return mono.get(n);
|
||
}
|
||
|
||
void Polynomial::add(int n) //添加项序第n小的单项式,如果该单项式已存在则抵消
|
||
{
|
||
mono.add(n); //将位图对应位置取反
|
||
}
|
||
void polynomial_mul(Polynomial& ret, Polynomial& p, Monomial& m)
|
||
{
|
||
Monomial mtemp;
|
||
for (int i = 0; i < M; i++)
|
||
{
|
||
if (p.get(i))
|
||
{
|
||
ret.add(mult_res[m.order][i]);
|
||
}
|
||
}
|
||
}
|
||
void Polynomial::set_leader_degree(int max_leader)
|
||
{
|
||
leader_order = mono.getleader();
|
||
if (leader_order != -1)
|
||
{
|
||
for (int i = 0; i <= D; i++)
|
||
{
|
||
degree = i;
|
||
if (leader_order < grevlex_degree_interval[i])
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
degree = -1;
|
||
}
|
||
}
|
||
Polynomial& Polynomial::operator ^=(Polynomial& p)
|
||
{
|
||
this->mono.xor_part(p.mono, 0, (max(leader_order, p.leader_order) - 1) / 64 + 2);
|
||
set_leader_degree(max(this->leader_order, p.leader_order));
|
||
return *this;
|
||
}
|
||
Polynomial& Polynomial::operator ^=(Sparse_Polynomial& p)
|
||
{
|
||
for (int i = 0; i < p.length; i++)
|
||
{
|
||
mono.add(p.sparse_mono[i]);
|
||
}
|
||
set_leader_degree(max(this->leader_order, p.leader_order));
|
||
return *this;
|
||
}
|
||
bool Polynomial::iszero()
|
||
{
|
||
if (mono.data_len <= 0 || leader_order < 0)
|
||
return true;
|
||
return false;
|
||
}
|
||
Monomial Polynomial::get_leader()
|
||
{
|
||
Monomial ret;
|
||
ret.from_order(leader_order);
|
||
return ret;
|
||
}
|
||
bool operator > (Polynomial& p, Polynomial& q)
|
||
{
|
||
return p.mono > q.mono;
|
||
}
|
||
|
||
bool operator < (Polynomial& p, Polynomial& q)
|
||
{
|
||
return p.mono < q.mono;
|
||
}
|