mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
380 lines
9.0 KiB
C++
380 lines
9.0 KiB
C++
/* mbinary
|
|
#########################################################################
|
|
# File : polynomial.cpp
|
|
# Author: mbinary
|
|
# Mail: zhuheqin1@gmail.com
|
|
# Blog: https://mbinary.xyz
|
|
# Github: https://github.com/mbinary
|
|
# Created Time: 2018-05-19 23:07
|
|
# Description:
|
|
#########################################################################
|
|
*/
|
|
|
|
#include<cstdlib>
|
|
#include<cstdio>
|
|
#include<cstring>
|
|
#include<cmath>
|
|
#include<malloc.h>
|
|
#include<map>
|
|
using namespace std;
|
|
|
|
#if defined(__linux__)
|
|
#define LINUX true
|
|
#elif defined(_WIN32)
|
|
#define LINUX false
|
|
#endif
|
|
|
|
|
|
bool isZero(double a)
|
|
{
|
|
if ((a < 0.00001) && -a < 0.00001)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
class node
|
|
{
|
|
friend class polynomial;
|
|
double coefficient;
|
|
double index;
|
|
};
|
|
class polynomial
|
|
{
|
|
int SIZE;
|
|
int n;
|
|
node* p;
|
|
public:
|
|
polynomial(int sz = 50);
|
|
polynomial(const polynomial &);
|
|
~polynomial();
|
|
double cal(double);
|
|
void getData();
|
|
void display();
|
|
polynomial operator=(const polynomial &);
|
|
polynomial operator+(const polynomial &);
|
|
polynomial operator-(const polynomial &);
|
|
polynomial operator*(const polynomial &);
|
|
};
|
|
polynomial::polynomial(int sz): n(0), SIZE(sz)
|
|
{
|
|
p = (node*) new node[SIZE];
|
|
memset(p, 0, sizeof(p));
|
|
}
|
|
polynomial::~polynomial()
|
|
{
|
|
delete p;
|
|
}
|
|
double polynomial::cal(double x)
|
|
{
|
|
double rst = 0;
|
|
|
|
for (int i = 0; i < n; ++i) {
|
|
rst += pow(x, p[i].index) * p[i].coefficient;
|
|
}
|
|
|
|
return rst;
|
|
}
|
|
polynomial::polynomial(const polynomial &a)
|
|
{
|
|
p = (node*) new node[50];
|
|
memset(p, 0, sizeof(p));
|
|
n = a.n;
|
|
|
|
for (int i = 0; i < a.n; ++i) {
|
|
p[i].index = a.p[i].index;
|
|
p[i].coefficient = a.p[i].coefficient;
|
|
}
|
|
}
|
|
polynomial polynomial::operator=(const polynomial& a)
|
|
{
|
|
n = a.n;
|
|
|
|
for (int i = 0; i < a.n; ++i) {
|
|
p[i].index = a.p[i].index;
|
|
p[i].coefficient = a.p[i].coefficient;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
void polynomial::display()
|
|
{
|
|
node * tmp = p;
|
|
|
|
if (n == 0) {
|
|
printf("0\n");
|
|
return;
|
|
}
|
|
|
|
// char *fmt = ("x"); printf(fmt,...);
|
|
for (int i = n - 1; i >= 0; --i) {
|
|
double t = tmp[i].coefficient;
|
|
double idx = tmp[i].index;
|
|
|
|
if (isZero(idx)) {
|
|
printf("%+g", t);
|
|
continue;
|
|
}
|
|
|
|
if (isZero(t - 1)) printf("+");
|
|
else if (isZero(t + 1))printf("-");
|
|
else printf("%+g", t);
|
|
|
|
printf("x");
|
|
|
|
if (!isZero(idx - 1)) printf("^%g", idx);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
void polynomial::getData()
|
|
{
|
|
printf("Please input data . \n");
|
|
printf("For every item,Coefficient first .Use space to separate,EOF to end\n");
|
|
map<double, double> mp;
|
|
double idx;
|
|
double coef;
|
|
|
|
while (scanf("%lf%lf", &coef, &idx) != EOF) {
|
|
if (isZero(coef)) continue;
|
|
|
|
if (mp.count(idx) == 0) {
|
|
mp[idx] = coef;
|
|
} else {
|
|
mp[idx] += coef;
|
|
|
|
if (isZero(mp[idx])) {
|
|
mp.erase(idx);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mp.size() > SIZE) {
|
|
SIZE *= 2;
|
|
p = (node*)realloc(p, sizeof(node) * SIZE) ;
|
|
}
|
|
|
|
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
|
|
p[n].index = it->first;
|
|
p[n++].coefficient = it->second;
|
|
}
|
|
}
|
|
polynomial polynomial::operator+(const polynomial & a)
|
|
{
|
|
polynomial rst ;
|
|
int p1 = 0, p2 = 0, p3 = 0;
|
|
double exp1 = p[p1].index;
|
|
double exp2 = a.p[p2].index;
|
|
|
|
while (p1 < n && p2 < a.n) {
|
|
while (p1 < n && exp1 < exp2) {
|
|
rst.p[p3].index = exp1;
|
|
rst.p[p3].coefficient = p[p1].coefficient;
|
|
++p1, ++p3;
|
|
exp1 = p[p1].index;;
|
|
}
|
|
|
|
while (p2 < a.n && exp1 > exp2) {
|
|
rst.p[p3].index = exp2;
|
|
rst.p[p3].coefficient = a.p[p2].coefficient;
|
|
++p2, ++p3;
|
|
exp2 = a.p[p2].index;;
|
|
}
|
|
|
|
if (isZero(exp1 - exp2)) {
|
|
double tmp = p[p1].coefficient + a.p[p2].coefficient;
|
|
|
|
if (isZero(tmp)) {
|
|
++p1, ++p2;
|
|
} else {
|
|
rst.p[p3].index = p[p1].index;
|
|
rst.p[p3].coefficient = tmp;
|
|
++p1, ++p2, ++p3;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (p1 == n) {
|
|
while (p2 < a.n) {
|
|
rst.p[p3].index = a.p[p2].index;
|
|
rst.p[p3].coefficient = a.p[p2].coefficient;
|
|
++p2, ++p3;
|
|
}
|
|
} else {
|
|
while (p1 < n) {
|
|
rst.p[p3].index = p[p1].index;
|
|
rst.p[p3].coefficient = p[p1].coefficient;
|
|
++p1, ++p3;
|
|
}
|
|
}
|
|
|
|
rst.n = p3;
|
|
return rst;
|
|
}
|
|
polynomial polynomial::operator-(const polynomial & a)
|
|
{
|
|
polynomial rst(a) ;
|
|
int i = 0;
|
|
|
|
while (i < rst.n) {
|
|
rst.p[i].coefficient = -rst.p[i].coefficient;
|
|
++i;
|
|
}
|
|
|
|
return (*this + rst);
|
|
}
|
|
polynomial polynomial::operator*(const polynomial & a)
|
|
{
|
|
map<double, double> mp;
|
|
|
|
for (int i = 0; i < n; ++i) {
|
|
double idx = p[i].index;
|
|
double coef = p[i].coefficient;
|
|
|
|
for (int j = 0; j < a.n; ++j) {
|
|
double index = idx + a.p[j].index;
|
|
|
|
if (mp.count(index) == 0) {
|
|
mp[index] = coef * a.p[j].coefficient;
|
|
} else {
|
|
mp[index] += coef * a.p[j].coefficient;
|
|
|
|
if (isZero(mp[index])) {
|
|
mp.erase(index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int sz = 50;
|
|
|
|
while (mp.size() > sz) {
|
|
sz *= 2;
|
|
}
|
|
|
|
polynomial rst(sz);
|
|
|
|
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
|
|
rst.p[rst.n].index = it->first;
|
|
rst.p[rst.n++].coefficient = it->second;
|
|
}
|
|
|
|
return rst;
|
|
}
|
|
int num = 0;
|
|
polynomial pl[30];
|
|
void menu()
|
|
{
|
|
printf("**********OPERATIONS***********\n");
|
|
printf("*****0. create *****\n");
|
|
printf("*****1. add + *****\n");
|
|
printf("*****2. sub - *****\n");
|
|
printf("*****3. mul * *****\n");
|
|
printf("*****4. display *****\n");
|
|
printf("*****5. menu *****\n");
|
|
printf("*****6. clear screen *****\n");
|
|
printf("*****7. exit *****\n");
|
|
printf("*****8. copy *****\n");
|
|
printf("*****9. display all *****\n");
|
|
printf("*****10. cal val *****\n");
|
|
printf("**********OPERATIONS***********\n");
|
|
}
|
|
void loop()
|
|
{
|
|
int op;
|
|
|
|
while (scanf("%d", &op) != EOF) {
|
|
if (op == 0) {
|
|
pl[num].getData();
|
|
++num;
|
|
printf("You've created polynomial %d:\n", num);
|
|
pl[num - 1].display();
|
|
} else if (op == 1 || op == 2 || op == 3) {
|
|
if (num < 2) {
|
|
printf("Oops! you've got less two polynomial\nPlease choose another operation\n");
|
|
continue;
|
|
}
|
|
|
|
printf("input two nums of the two polynomial to be operated.eg: 1 2\n");
|
|
int t1 = 100, t2 = 100;
|
|
|
|
while (1) {
|
|
scanf("%d%d", &t1, &t2);
|
|
|
|
if (t1 > num || t2 > num || t1 < 0 || t2 < 0) {
|
|
printf("wrong num ,please input again\n");
|
|
} else break;
|
|
}
|
|
|
|
printf("the rst is:\n");
|
|
t1 -= 1, t2 -= 1;
|
|
|
|
if (op == 1) {
|
|
(pl[t1] + pl[t2]).display();
|
|
} else if (op == 2) {
|
|
(pl[t1] - pl[t2]).display();
|
|
} else (pl[t1]*pl[t2]).display();
|
|
} else if (op == 4) {
|
|
printf("input a polynomial's num to display it\n");
|
|
int tmp;
|
|
scanf("%d", &tmp);
|
|
|
|
if (tmp > num) {
|
|
printf("wrong num");
|
|
} else {
|
|
printf("info of polynomial %d\n", tmp);
|
|
pl[tmp - 1].display();
|
|
}
|
|
} else if (op == 9) {
|
|
for (int i = 0; i < num; ++i) {
|
|
printf("polynomial %d : ", i + 1);
|
|
pl[i].display();
|
|
}
|
|
} else if (op == 5) {
|
|
menu();
|
|
} else if (op == 6) {
|
|
if (LINUX) system("clear");
|
|
else system("cls");
|
|
|
|
menu();
|
|
} else if (op == 10) {
|
|
double x;
|
|
int t;
|
|
printf("choose a polynomial\n");
|
|
scanf("%d", &t);
|
|
|
|
if (t > num || t < 0) {
|
|
printf("wrong num\n");
|
|
} else {
|
|
printf("input a value\n");
|
|
scanf("%lf", &x);
|
|
pl[t - 1].display();
|
|
printf("%g\n", pl[t - 1].cal(x));
|
|
}
|
|
} else if (op == 8) {
|
|
if (num == 0) {
|
|
printf("you have'nt any polynomial tp copy\n");
|
|
continue;
|
|
}
|
|
|
|
int n = num + 1;
|
|
|
|
while (n > num) {
|
|
printf("input the number of an existing polynomial you want to copy\n");
|
|
scanf("%d", &n);
|
|
}
|
|
|
|
(pl[num] = pl[n - 1]);
|
|
printf("You've copyed this polynomial:\n");
|
|
pl[num++].display();
|
|
} else exit(0);
|
|
|
|
printf("select an operation\n");
|
|
}
|
|
}
|
|
int main(void)
|
|
{
|
|
menu();
|
|
loop();
|
|
return 0;
|
|
}
|