这是哈工大数据结构课的一个实验作业,试验结束了,终于可以发出来了。
实验要求:
实验 1 线性结构及其应用
实验项目:线性表的链式存储结构与应用
实验题目:一元多项式计算器
实验内容:
设计线性表的动态或者静态链式存储结构,并实现一个一元多项式的计算器。
实验要求: 以动态或者静态链表存储一元多项式,在此基础上按要求完成对一元多项式
的运算。(为保证多项式的值的准确性,多项式的系数可以用分数表示,涉及到
两个分数相除时,结果也可以用分数表示。)
- 能够输入多项式(可以按各项的任意输入顺序,建立按指数降幂排列的多项
式)和输出多项式(按指数降幂排列),以文件形式输入和输出,并显示。 - 能够给出计算两个多项式加法、减法、乘法和除法运算的结果多项式,除法
运算的结果包括商多项式和余数多项式。 - 能够计算一元多项式的 k 阶导函数。
- 能够计算多项式在某一点 x=x0 的值,其中 x0是一个浮点型常量,返回结果为
浮点数。 - 要求尽量减少乘法和除法运算中间结果的空间占用和结点频繁的分配与回收
操作。(提示:利用循环链表结构或者可用空间表的思想,把循环链表表示
的多项式返还给系统或者可用空间表,从而解决上述问题)。
下面是源码:
#include <iostream>
#include <cstdio>
#include <math.h>
#include <cstdlib>
struct NODE
{
float coef;//系数
int expo;//指数
NODE* next;
};
typedef NODE* LIST;
struct result{
LIST Quotient;
LIST Remainder;
};
void add(float coef, int expo,LIST p){
if (p == NULL){
printf("指针为空,异常!");
return;
}
while (p->next != NULL){
p = p->next;
}
NODE* newnode = (NODE*)malloc(sizeof(NODE));
newnode->coef = coef;
newnode->expo = expo;
newnode->next = NULL;
p->next = newnode;
}
//释放头节点以外的地址空间
void Destroy(LIST L){
LIST p1 = L;
LIST p2 = L->next;
while (p2 != NULL){
p1->next = p2->next;
delete p2;
p2 = p1->next;
}
}
//打印L中的多项式
void Print(LIST L){
if (L == NULL){
printf("读取错误!");
return;
}
L = L->next;
printf("%.2fx^%d",L->coef, L->expo);
L = L->next;
while (L->next!= NULL){
printf("%c%.2fx^%d",L->coef>0 ? '+' :'\0', L->coef, L->expo);
L = L->next;
}
if (L->expo == 0){
printf("%c%.2f",L->coef>0 ? '+' :'\0', L->coef);
}
else{
printf("%c%.2fx^%d",L->coef>0 ? '+' :'\0', L->coef, L->expo);
}
printf("\n");
}
//从文件ff中读入数据,并返回一个结构体指针
LIST read(FILE *ff){
int exp;
float coe;
char ch;
LIST p = new struct NODE;
p->next = NULL;
ch = fgetc(ff);
if (ch != '-'){
rewind(ff);
fscanf(ff,"%fx^%d",&coe,&exp);
add(coe,exp,p);
}
else{
fscanf(ff,"%fx^%d",&coe,&exp);
add((-coe),exp,p);
}
while (fscanf(ff,"%c%fx^%d",&ch,&coe,&exp) != EOF){
if (ch == '+'){
add(coe,exp,p);
}
if (ch == '-'){
add((-coe),exp,p);
}
}
return p;
}
//将L中的多项式节点按指数降序排列
void PowerDown(LIST L){
if (L == NULL){
printf("指针为空,异常!");
return;
}
LIST pr = L->next,pr1 = L;
LIST p2 = NULL,p1 = NULL;
LIST q = NULL,q1 = NULL;
LIST temp = NULL;
while (pr->next != NULL){
q = pr;
p1 = pr;
p2 = pr->next;
while (p2 != NULL){
if (p2->expo <= q->expo){
p2 = p2->next;
p1 = p1->next;
}
else{
q1 = p1;
q = p2;
p2 = p2->next;
p1 = p1->next;
}
}
if (q != pr){
if(pr == q1){
pr1->next = q1->next;
q1->next = q->next;
q->next = q1;
pr1 = pr1->next;
}
else{
temp = pr ->next;
pr->next = q->next;
q1->next = pr;
q->next = temp;
pr1->next = q;
pr = q->next;
pr1 = pr1->next;
}
}
else{
pr = pr->next;
pr1 = pr1->next;
}
}
}
//去除系数为零的项
void DelZero(LIST J){
if (J == NULL){
printf("指针为空,异常!");
return;
}
LIST y1 = J;
LIST y2 = y1->next;
while (y2 != NULL){
if (y2->coef == 0){
y1->next = y2->next;
delete y2;
y2 = y1->next;
}
else{
y1 = y1->next;
y2 = y2->next;
}
}
}
//加法
LIST addition(LIST p,LIST q){
if (p == NULL||q == NULL){
printf("指针为空,异常!");
return NULL;
}
LIST L = new struct NODE;
LIST end = L;
L->next = NULL;
q = q->next;
p = p->next;
while (p != NULL&&q != NULL){
if (p->expo > q->expo){
add(p->coef,p->expo,L);
end = end->next;
p = p->next;
}
else if (q->expo > p->expo){
add(q->coef,q->expo,L);
end = end->next;
q = q->next;
}
else{
add((p->coef+q->coef),p->expo,L);
end = end->next;
p = p->next;
q = q->next;
}
}
if (p == NULL){
end->next = q;
}
else{
end->next = p;
}
DelZero(L);
return L;
}
//m中的多项式减n中的多项式
LIST Subtraction(LIST m,LIST n){
if (m == NULL||n == NULL){
printf("指针为空,异常!");
return NULL;
}
LIST L = n ->next;
float temp;
while (L != NULL){
temp = L->coef;
L->coef = -temp;
L= L->next;
}
return addition(m,n);
}
//乘完之后合并同类项
LIST MergeSimilar(LIST D){
if (D == NULL){
printf("指针为空,异常!");
return NULL;
}
LIST w = D->next;
LIST del = NULL;
LIST v = NULL,vr = NULL;
int temp;
while (w != NULL){
v = w->next;
vr = w;
while (v != NULL){
if (w->expo == v->expo){
temp = w->coef;
w->coef = temp + v->coef;
del = v;
vr ->next = v->next;
delete del;
v = vr->next;
}
else{
v = v->next;
vr = vr->next;
}
}
w = w->next;
}
PowerDown(D);
return D;
}
//乘法
LIST multiplication(LIST x,LIST y){
if (x == NULL||y == NULL){
printf("指针为空,异常!");
return NULL;
}
LIST a = x->next;
LIST b = y->next;
LIST K = new struct NODE;
K->next = NULL;
while (a != NULL){
b = y->next;
while (b != NULL){
add((a->coef*b->coef),(a->expo+b->expo),K);
b = b->next;
}
a = a->next;
}
return MergeSimilar(K);
}
//除法,b中的多项式除以d中的多项式
struct result *division(LIST b,LIST d){
if (b == NULL||d == NULL){
printf("指针为空,异常!");
return NULL;
}
LIST Quotient = new struct NODE;
Quotient->next = NULL;
struct result *res = new struct result;
res->Remainder = NULL;
res->Quotient = NULL;
LIST Quo = new struct NODE;
Quo->next = NULL;
LIST b1 = NULL,b2 = NULL,b4 = NULL,temp = NULL;
LIST b3 = new struct NODE;
b3->next = NULL;
b1 = b;
b2 = d->next;
add(b1->next->coef/b2->coef,b1->next->expo-b2->expo,Quo);
add(b1->next->coef/b2->coef,b1->next->expo-b2->expo,Quotient);
add(b2->coef,b2->expo,b3);
b4 = multiplication(Quo,d);
temp = Subtraction(b1,b4);
b1 = temp;
Destroy(Quo);
delete b4;
while (b1->next->expo >= b2->expo){
add(b1->next->coef/b2->coef,b1->next->expo-b2->expo,Quo);
add(b1->next->coef/b2->coef,b1->next->expo-b2->expo,Quotient);
b4 = multiplication(Quo,d);
temp = Subtraction(b1,b4);
delete b1;
b1 = temp;
Destroy(Quo);
delete b4;
}
res->Quotient = Quotient;
res->Remainder = b1;
return res;
}
//求导
LIST Derivation(LIST c){
if (c == NULL){
printf("指针为空,异常!");
return NULL;
}
LIST p = c->next;
float coe;
int exp;
while (p != NULL){
coe = p->coef;
exp = p->expo;
p->coef = coe*exp;
p->expo = exp-1;
p = p->next;
}
DelZero(c);
}
//计算多项式中的变量取x时多项式的值
void Calculation(LIST K,float x){
if (K == NULL){
printf("指针为空,异常!");
return;
}
LIST p = K->next;
float fl = 0;
while (p != NULL){
fl += p->coef * pow(x, p->expo);
p = p->next;
}
printf("%f\n",fl);
}
//将多项式M写入文件output.txt
void WriteFile(LIST M){
if (M == NULL){
printf("指针为空,异常!");
return;
}
FILE *fp = NULL;
LIST pp = M->next;
fp = fopen("../output.txt","a");
char ch;
ch = getc(fp);
if (ch != '-'){
rewind(fp);
fprintf(fp,"%.3fx^%d",pp->coef,pp->expo);
}
else{
rewind(fp);
fprintf(fp,"-%.3fx^%d",pp->coef,pp->expo);
}
pp = pp->next;
while (pp != NULL){
if (pp->coef>0){
fprintf(fp,"+%.3fx^%d",pp->coef,pp->expo);
}
else{
fprintf(fp,"-%.3fx^%d",pp->coef,pp->expo);
}
pp = pp->next;
}
fprintf(fp,"\n");
fclose(fp);
}
int main() {
FILE *fp1 = NULL;
FILE *fp2 = NULL;
LIST p1 = NULL;
LIST p2 = NULL;
LIST p3 = NULL;
float x = 0;
struct result *p4 = NULL;
int Options = 0;
fp1 = fopen("../input1.txt", "r");
fp2 = fopen("../input2.txt", "r");
if (fp1 != NULL) {
p1 = read(fp1);
}
if (fp2 != NULL) {
p2 = read(fp2);
}
fclose(fp1);
fclose(fp2);
PowerDown(p1);
PowerDown(p2);
while (1){
printf("多项式p1:");
Print(p1);
printf("多项式p2:");
Print(p2);
printf("请您进行选择:\n1.多项式加法p1+p2\n2.多项式减法p1-p2\n3.多项式乘p1*p2\n4.多项式除法p1/p2\n5.对p1求导\n6.多项式p1求值\n7.多项式p2求值\n8.结束\n");
scanf("%d",&Options);
switch (Options) {
case 1:
p3 = addition(p1,p2);
if (p3 == NULL){
exit(0);
}
printf("相加结果为:");
Print(p3);
WriteFile(p3);
break;
case 2:
p3 = Subtraction(p1,p2);
if (p3 == NULL){
exit(0);
}
printf("相减结果为:");
Print(p3);
WriteFile(p3);
break;
case 3:
p3 = multiplication(p1,p2);
if (p3 == NULL){
exit(0);
}
printf("相乘结果为:");
Print(p3);
WriteFile(p3);
break;
case 4:
p4 = division(p1,p2);
if (p4 == NULL){
exit(0);
}
printf("商多项式为:");
Print(p4->Remainder);
printf("余数多项式为:");
Print(p4->Quotient);
WriteFile(p4->Quotient);
WriteFile(p4->Remainder);
break;
case 5:
p3 = Derivation(p1);
if (p3 == NULL){
exit(0);
}
printf("p1求导结果为:");
Print(p3);
WriteFile(p3);
break;
case 6:
printf("输入x:");
scanf("%f",&x);
Calculation(p1,x);
break;
case 7:
printf("输入x:");
scanf("%f",&x);
Calculation(p2,x);
break;
case 8:
exit(0);
}
}
return 0;
}
收获:
1.c++相对路径
2.文件的读写操作
3.多项式除法的算法实现