algorithm-in-python/dataStructure/polynomial.cpp

380 lines
9.0 KiB
C++
Raw Normal View History

2018-07-08 23:28:29 +08:00
/* mbinary
#########################################################################
# File : polynomial.cpp
# Author: mbinary
# Mail: zhuheqin1@gmail.com
2019-01-31 12:09:46 +08:00
# Blog: https://mbinary.xyz
2018-07-08 23:28:29 +08:00
# Github: https://github.com/mbinary
# Created Time: 2018-05-19 23:07
# Description:
#########################################################################
*/
2020-04-15 12:28:20 +08:00
#include<cstdlib>
2018-07-15 11:20:52 +08:00
#include<cstdio>
#include<cstring>
#include<cmath>
2018-07-08 23:28:29 +08:00
#include<malloc.h>
#include<map>
using namespace std;
2018-07-15 11:20:52 +08:00
#if defined(__linux__)
2020-04-15 12:28:20 +08:00
#define LINUX true
2018-07-15 11:20:52 +08:00
#elif defined(_WIN32)
2020-04-15 12:28:20 +08:00
#define LINUX false
2018-07-15 11:20:52 +08:00
#endif
2018-07-08 23:28:29 +08:00
bool isZero(double a)
{
2020-04-15 12:28:20 +08:00
if ((a < 0.00001) && -a < 0.00001)
2018-07-08 23:28:29 +08:00
return true;
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
return false;
}
class node
{
friend class polynomial;
double coefficient;
double index;
};
class polynomial
{
int SIZE;
int n;
node* p;
2020-04-15 12:28:20 +08:00
public:
polynomial(int sz = 50);
polynomial(const polynomial &);
2018-07-08 23:28:29 +08:00
~polynomial();
double cal(double);
void getData();
void display();
polynomial operator=(const polynomial &);
polynomial operator+(const polynomial &);
polynomial operator-(const polynomial &);
polynomial operator*(const polynomial &);
};
2020-04-15 12:28:20 +08:00
polynomial::polynomial(int sz): n(0), SIZE(sz)
2018-07-08 23:28:29 +08:00
{
p = (node*) new node[SIZE];
2020-04-15 12:28:20 +08:00
memset(p, 0, sizeof(p));
2018-07-08 23:28:29 +08:00
}
polynomial::~polynomial()
{
delete p;
}
double polynomial::cal(double x)
{
2020-04-15 12:28:20 +08:00
double rst = 0;
for (int i = 0; i < n; ++i) {
rst += pow(x, p[i].index) * p[i].coefficient;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
return rst;
}
polynomial::polynomial(const polynomial &a)
{
p = (node*) new node[50];
2020-04-15 12:28:20 +08:00
memset(p, 0, sizeof(p));
2018-07-08 23:28:29 +08:00
n = a.n;
2020-04-15 12:28:20 +08:00
for (int i = 0; i < a.n; ++i) {
2018-07-08 23:28:29 +08:00
p[i].index = a.p[i].index;
p[i].coefficient = a.p[i].coefficient;
}
}
polynomial polynomial::operator=(const polynomial& a)
{
n = a.n;
2020-04-15 12:28:20 +08:00
for (int i = 0; i < a.n; ++i) {
2018-07-08 23:28:29 +08:00
p[i].index = a.p[i].index;
p[i].coefficient = a.p[i].coefficient;
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
return *this;
}
void polynomial::display()
{
node * tmp = p;
2020-04-15 12:28:20 +08:00
if (n == 0) {
2018-07-08 23:28:29 +08:00
printf("0\n");
return;
}
2020-04-15 12:28:20 +08:00
// char *fmt = ("x"); printf(fmt,...);
for (int i = n - 1; i >= 0; --i) {
2018-07-08 23:28:29 +08:00
double t = tmp[i].coefficient;
double idx = tmp[i].index;
2020-04-15 12:28:20 +08:00
if (isZero(idx)) {
printf("%+g", t);
2018-07-08 23:28:29 +08:00
continue;
}
2020-04-15 12:28:20 +08:00
if (isZero(t - 1)) printf("+");
else if (isZero(t + 1))printf("-");
else printf("%+g", t);
2018-07-08 23:28:29 +08:00
printf("x");
2020-04-15 12:28:20 +08:00
if (!isZero(idx - 1)) printf("^%g", idx);
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
printf("\n");
}
void polynomial::getData()
{
printf("Please input data . \n");
printf("For every item,Coefficient first .Use space to separate,EOF to end\n");
2020-04-15 12:28:20 +08:00
map<double, double> mp;
2018-07-08 23:28:29 +08:00
double idx;
double coef;
2020-04-15 12:28:20 +08:00
while (scanf("%lf%lf", &coef, &idx) != EOF) {
if (isZero(coef)) continue;
if (mp.count(idx) == 0) {
2018-07-08 23:28:29 +08:00
mp[idx] = coef;
2020-04-15 12:28:20 +08:00
} else {
2018-07-08 23:28:29 +08:00
mp[idx] += coef;
2020-04-15 12:28:20 +08:00
if (isZero(mp[idx])) {
2018-07-08 23:28:29 +08:00
mp.erase(idx);
}
}
}
2020-04-15 12:28:20 +08:00
if (mp.size() > SIZE) {
SIZE *= 2;
p = (node*)realloc(p, sizeof(node) * SIZE) ;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
2018-07-08 23:28:29 +08:00
p[n].index = it->first;
p[n++].coefficient = it->second;
}
}
polynomial polynomial::operator+(const polynomial & a)
{
polynomial rst ;
2020-04-15 12:28:20 +08:00
int p1 = 0, p2 = 0, p3 = 0;
2018-07-08 23:28:29 +08:00
double exp1 = p[p1].index;
double exp2 = a.p[p2].index;
2020-04-15 12:28:20 +08:00
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;;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
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;;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
if (isZero(exp1 - exp2)) {
double tmp = p[p1].coefficient + a.p[p2].coefficient;
if (isZero(tmp)) {
++p1, ++p2;
} else {
2018-07-08 23:28:29 +08:00
rst.p[p3].index = p[p1].index;
rst.p[p3].coefficient = tmp;
2020-04-15 12:28:20 +08:00
++p1, ++p2, ++p3;
2018-07-08 23:28:29 +08:00
}
}
}
2020-04-15 12:28:20 +08:00
if (p1 == n) {
while (p2 < a.n) {
2018-07-08 23:28:29 +08:00
rst.p[p3].index = a.p[p2].index;
rst.p[p3].coefficient = a.p[p2].coefficient;
2020-04-15 12:28:20 +08:00
++p2, ++p3;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
} else {
while (p1 < n) {
2018-07-08 23:28:29 +08:00
rst.p[p3].index = p[p1].index;
rst.p[p3].coefficient = p[p1].coefficient;
2020-04-15 12:28:20 +08:00
++p1, ++p3;
2018-07-08 23:28:29 +08:00
}
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
rst.n = p3;
return rst;
}
polynomial polynomial::operator-(const polynomial & a)
{
polynomial rst(a) ;
int i = 0;
2020-04-15 12:28:20 +08:00
while (i < rst.n) {
2018-07-08 23:28:29 +08:00
rst.p[i].coefficient = -rst.p[i].coefficient;
++i;
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
return (*this + rst);
}
polynomial polynomial::operator*(const polynomial & a)
{
2020-04-15 12:28:20 +08:00
map<double, double> mp;
for (int i = 0; i < n; ++i) {
2018-07-08 23:28:29 +08:00
double idx = p[i].index;
double coef = p[i].coefficient;
2020-04-15 12:28:20 +08:00
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])) {
2018-07-08 23:28:29 +08:00
mp.erase(index);
}
}
}
}
2020-04-15 12:28:20 +08:00
int sz = 50;
while (mp.size() > sz) {
sz *= 2;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
polynomial rst(sz);
2020-04-15 12:28:20 +08:00
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
2018-07-08 23:28:29 +08:00
rst.p[rst.n].index = it->first;
rst.p[rst.n++].coefficient = it->second;
}
2020-04-15 12:28:20 +08:00
2018-07-08 23:28:29 +08:00
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;
2020-04-15 12:28:20 +08:00
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;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
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;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
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();
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
} else if (op == 9) {
for (int i = 0; i < num; ++i) {
printf("polynomial %d : ", i + 1);
pl[i].display();
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
} 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));
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
} else if (op == 8) {
if (num == 0) {
printf("you have'nt any polynomial tp copy\n");
continue;
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
int n = num + 1;
while (n > num) {
printf("input the number of an existing polynomial you want to copy\n");
scanf("%d", &n);
2018-07-08 23:28:29 +08:00
}
2020-04-15 12:28:20 +08:00
(pl[num] = pl[n - 1]);
printf("You've copyed this polynomial:\n");
pl[num++].display();
} else exit(0);
printf("select an operation\n");
2018-07-08 23:28:29 +08:00
}
}
int main(void)
{
menu();
loop();
return 0;
}