文章目录
大致内容介绍
作为实验三的补充,本次多项式加法和乘法是利用链表来实现的,实际上使用key-value来实现更便于操作。
多项式加法代码一览
头文件Poly.h内容如下:
//多项式:polynomial
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#pragma warning(disable:4996)
#pragma warning(disable:6031)
#pragma warning(disable:6011)
//形如AX^B的一个结点
typedef struct _PolyNode {
int A; //系数
int B; //指数
struct _PolyNode* next;
}PolyNode, * pPolyNode;
//一个多项式抽象为链表
typedef struct _Poly {
pPolyNode head;
} Poly, * pPoly;
//初始化
void PolyInit(pPoly list);
//添加
void PolyAddt(pPoly list, int A, int B);
void PolyAddh(pPoly list, int A, int B);
void PolyAddp(pPoly list, int pos, int A, int B);
//遍历
void PolyVisit(Poly list);
PolyNode PolyVisit(Poly list, int pos);
void PolyVisit(Poly list, int from, int to);
//删除,分别是尾部删除和对应位置删除
void PolyDelt(pPoly list);
void PolyDelp(pPoly list, int pos);
//判断
int isEmpty(Poly list);
int getPos(Poly list, int A, int B);
int isExist(Poly list, int A, int B);
int getLength(Poly list);
void clearList(pPoly list);
void releaseList(pPoly list);
void PolyTraverse(Poly list);
Poly PolyAdd(Poly pl1, Poly pl2);
int PolyCreate(pPoly list, char* Expression);
void PolyInsertElem(pPoly list, int coef, int exp);
实现文件Poly.cpp内容如下:
初始化
void PolyInit(pPoly list){
list->head = (pPolyNode)malloc(sizeof(PolyNode));
list->head->next = NULL;
}
增加元素
//尾部增加
void PolyAddt(pPoly list, int A,int B){
pPolyNode move = list->head;
while (move->next) move = move->next;
pPolyNode add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = A;
add->B = B;
add->next = NULL;
move->next = add;
}
//头部增加
void PolyAddh(pPoly list, int A,int B) {
pPolyNode move = list->head->next;
pPolyNode add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = A;
add->B = B;
add->next = move;
list->head->next = add;
}
//指定位置增加
void PolyAddp(pPoly list, int pos, int A,int B) {
pPolyNode move = list->head;
int j = 1;
if (j > pos) return;
while (move!=NULL && j < pos) {
move = move->next;
++j;
}
if (move == NULL) return;
pPolyNode add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = A;
add->B = B;
add->next = NULL;
add->next = move->next;
move->next = add;
}
删除元素
//尾部删除
void PolyDelt(pPoly list) {
pPolyNode move = list->head;
pPolyNode tmp = list->head->next;
while (tmp->next!=NULL) {
tmp = tmp->next;
move = move->next;
}
move->next = NULL;
free(tmp);
}
//指定位置删除
void PolyDelp(pPoly list, int pos) {
pPolyNode move = list->head;
int j = 1;
if (j > pos) return;
while (move->next && j < pos) {
move = move->next;
++j;
}
if (move->next == NULL) return;
pPolyNode tmp = move->next;
move->next = tmp->next;
free(tmp);
}
功能函数
int isEmpty(Poly list) {
return list.head->next == NULL;
}
int getPos(Poly list, int A, int B) {
pPolyNode move = list.head->next;
int j = 1;
while (move && move->A != A && move->B != B) {
move = move->next;
++j;
}
if (move == NULL) return -1;
else return j;
}
int isExist(Poly list, int A, int B) {
return getPos(list, A, B) != -1;
}
int getLength(Poly list) {
pPolyNode move = list.head->next;
int j = 0;
while (move) {
move = move->next;
++j;
}
return j;
}
遍历函数
void PolyVisit(Poly list) {
pPolyNode move = list.head->next;
printf("链表中的元素为:");
while (move) {
printf("%d %d", move->A, move->B);
move = move->next;
}
printf("\n");
}
PolyNode PolyVisit(Poly list, int pos) {
pPolyNode move = list.head->next;
int j = 1;
if (j > pos) return { 0,0 };
while (move && j < pos) {
move = move->next;
++j;
}
PolyNode invalid_data = { INT_MAX,INT_MAX };
if (move == NULL) return invalid_data;
return *move;
}
void PolyVisit(Poly list, int from, int to) {
int j = 1;
if (from < j) return;
pPolyNode move = list.head->next;
while (move && j < from) {
move = move->next;
++j;
}
printf("链表中%d 到%d 的元素为:", from, to);
while (move && j <= to) {
printf("%d %d", move->A, move->B);
move = move->next;
++j;
}
printf("\n");
}
清除销毁
void clearList(pPoly list) {
pPolyNode move = list->head->next;
pPolyNode tmp;
while (move) {
tmp = move;
move = move->next;
free(tmp);
}
list->head->next = NULL;
}
void releaseList(pPoly list) {
pPolyNode move = list->head;
pPolyNode tmp;
while (move) {
tmp = move;
move = move->next;
free(tmp);
}
}
void PolyTraverse(Poly list) {
pPolyNode move = list.head->next;
if (move) {
printf("%dx^%d ", move->A, move->B);
move = move->next;
while (move) {
if (move->A > 0) printf(" + %dx^%d ", move->A, move->B);
else printf(" - %dx^%d ", -1 * (move->A), move->B);
move = move->next;
}
}
else printf("0");printf("\n");
}
打印多项式
void PolyInsertElem(pPoly list, int A, int B) {
pPolyNode move = list->head->next;
pPolyNode tmp = list->head;
while (move && move->B < B) {
tmp = tmp->next;
move = move->next;
}
if (move && move->B == B) {
move->A += A;
if (move->A == 0) {
tmp->next = move->next;
free(move);
}
}
else {
pPolyNode add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = A;
add->B = B;
add->next = move;
tmp->next = add;
}
}
创建多项式
int PolyCreate(pPoly list, char* Expression) {
//用状态机表示输入的表达式 5 中状态(初始,符号,系数,x,指数),5 种条件(空格,+ -,数字,x, ^)
int tran[5][5] =
{ {0, 1, 2, 3, -1},
{1, -1, 2, 3, -1},
{ 2,1,2,3,4 },
{3, 1, -1, -1, 4},
{4, 1, 4, -1, -1}};
int state = 0;
int A = 0;
int B = 0;
int i = 0;
int signal = 1;
while (Expression[i] != '\0') {
switch (Expression[i]) {
case ' ':
state = tran[state][0];
break;
case '+': {
if (coef != 0) {
PolyInsertElem(list, A, B);
}
state = tran[state][1];
A = 0;
B = 0;
signal = 1;
break;
}
case '-': {
if (coef != 0) {
PolyInsertElem(list, A, B);
}
state = tran[state][1];
A = 0;
B = 0;
signal = -1;
break;
}
case '^': {
state = tran[state][4];
B = 0;
break;
}
case 'x': {//修改代码
state = tran[state][3];
if (A == 0) A= 1;
A = A * signal;
exp = 1;
break;
}
default: {
if (Expression[i] >= '0' && Expression[i] <= '9') {
state = tran[state][2];
if (state == 2) {
A = A * 10 + Expression[i] - '0';
}
if (state == 4) {
B = B * 10 + Expression[i] - '0';
}
}
else {
state = -1;
}
}
}
if (state == -1) return -1;
i++;
}
PolyInsertElem(list, signal * A, B);
return 0;
}
向多项式内插入一个元素
Poly PolyAdd(Poly pl1, Poly pl2) {
pPolyNode move = pl1.head->next;
pPolyNode tmp = pl2.head->next;
Poly pl3;
PolyInit(&pl3);
pPolyNode r = pl3.head;
pPolyNode add;
while (move && tmp) {
if (move->B < tmp->B) {
add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = move->A;
add->B = move->B;
add->next = NULL;
move = move->next;
r->next = add;
//add=add->next;
r = r->next;
}
else if (move->B == tmp->B) {
if (move->A + tmp->A != 0) {
add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = move->A + tmp->A;
add->B = move->B;
add->next = NULL;
r->next = add;
//add=add->next;
r = r->next;
}
move = move->next;
tmp = tmp->next;
}
else {
add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = tmp->A;
add->B = tmp->B;
add->next = NULL;
tmp = tmp->next;
r->next = add;
//add=add->next;
r = r->next;
}
}
while (move) {
add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = move->A;
add->B = move->B;
add->next = NULL;
move = move->next;
r->next = add;
//add=add->next;
r = r->next;
}
while (tmp) {
add = (pPolyNode)malloc(sizeof(PolyNode));
add->A = tmp->A;
add->B = tmp->B;
add->next = NULL;
tmp = tmp->next;
r->next = add;
//add=add->next;
r = r->next;
}
return pl3;
}
源文件main.cpp内容如下:
#include"Poly.h"
int main()
{
Poly pl1, pl2, pl3;
PolyInit(&pl1);
PolyInit(&pl2);
char putin[1000];
printf("请输入第一个表达式 :\n");
scanf("%s", putin);
while (PolyCreate(&pl1, putin) == -1) {
printf("表达式输入错误,请重新输入:\n");
scanf("%s", putin);
}
printf("表达式 1:");
PolyTraverse(pl1);
printf("请输入第二个表达式 :\n");
scanf("%s", putin);
while (PolyCreate(&pl2, putin) == -1) {
printf("输入错误,请重新输入:\n");
scanf("%s", putin);
}
printf("表达式 2:");
PolyTraverse(pl2);
pl3 = PolyAdd(pl1, pl2);
printf("求和结果为:");
PolyTraverse(pl3);
return 0;
}
实现效果:
多项式乘法
设计算法实现多项式求乘积难点在于,对于长短不一的多项式要交错相乘,得到次数相同的多项式后,需要合并同次。若多项式都是N项,时间复杂度为O(n2)。
实现方法:
在Poly.h中添加声明:
Poly PolyMul(Poly lst1, Poly lst2);
在Poly.cpp中添加实现:
Poly PolyMul(Poly lst1, Poly lst2) {
pPolyNode m1 = lst1.head->next;
pPolyNode m2 = lst2.head->next;
Poly m3 = {};
PolyInit(&m3);
for (int i = 0; i < getLength(lst2); i++) {
for (int j = 0; j < getLength(lst1); j++) {
PolyInsertElem(&m3, (m1->A) * (m2->A), (m1->B) + (m2->B));
if (m1->next != NULL)m1 = m1->next;
}
m1 = lst1.head->next;
if (m2->next != NULL)m2 = m2->next;
}
return m3;
}