一元稀疏多项式加法计算器——C语言实现

#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0

typedef int ReturnValue;
typedef struct Polynode {
	float coef; // 系数
	int exp;  // 指数
	struct Polynode* next;
}Polynode, * Polylist;

//输入数据, 边输入边排序进链表
ReturnValue InputDataAndSortingData(Polylist Polynomial, int n);

//初始化多项式链表
void Init(Polylist& Polynomial);

//将两个多项式相加
void PolynomialAdd(Polylist A, Polylist B);

// 输出计算结果
void DisplayResult(Polylist A);

// 指令输入与判断
int Input_judgefun(int function);

// 显示菜单
void Menu();

// 关于我们
void AboutUs();

int main() {
	Menu();
	int function;
	function = Input_judgefun(function);
	while (function) {
		switch (function) {
		case 1:
			int n1; // n1 为多项式 A 的项数
			printf("请输入第一个多项式的项数:");
			scanf("%d", &n1);
			Polylist A;
			Init(A); // 初始化链表 A 
			if (InputDataAndSortingData(A, n1) == ERROR) {
				printf("您输入了非法数据,程序已自动退出!\n");
				return 0;
			} // 输入并整理数据 

			int n2;// n2 为多项式 B 的项数
			printf("请输入第二个多项式的项数:");
			scanf("%d", &n2);
			Polylist B;
			Init(B);// 初始化链表 B 
			if (InputDataAndSortingData(A, n1) == ERROR) {
				printf("您输入了非法数据,程序已自动退出!\n");
				return 0;
			} // 输入并整理数据 

			PolynomialAdd(A, B); // 进入函数开始计算 
			DisplayResult(A); // 显示计算结果 
			break;
		case 2:
			AboutUs();
			break;
		}

		printf("请输入下一步指令:\n");
		function = Input_judgefun(function);
	}
	printf("感谢使用!\n");
}


//输入数据, 边输入边排序进链表
int InputDataAndSortingData(Polylist Polynomial, int n) {
	if (n == 0) {
		// 项数为零,直接返回 
		return OK;
	}
	int i;
	Polylist q, p;
	q = (Polylist)malloc(sizeof(Polynode));
	p = (Polylist)malloc(sizeof(Polynode));
	printf("请依次输入每一项的系数和指数:\n");
	for (i = 1; i <= n; i++) {
		Polylist s = (Polylist)malloc(sizeof(Polynode));
		if (scanf("%f", &s->coef) == 0 || scanf("%d", &s->exp) == 0) {
			free(s);
			return ERROR;
		}
		if (!(Polynomial->next)) { // 插入第一个结点
			s->next = Polynomial->next;
			Polynomial->next = s;
		}
		else {
			// p、q 均为工作指针,其中 q 在前,p 在后 
			q = Polynomial;
			p = Polynomial->next;
			while (p) {
				if (s->exp > p->exp) {
					// 如果要插入的结点 s 的 exp 值大于 p 结点的 exp 值就将 s 插入到  p 结点之前 
					s->next = p;
					q->next = s;
					break;
				}
				else if (s->exp == p->exp) {
					// 如果指数相等,就将输入的系数和对应指数相等的结点中的系数值相加 
					// 同时释放结点 s 的内存 
					p->coef = s->coef + p->coef;
					free(s);
					break;
				}
				// p、q 指针后移 
				q = q->next;
				p = p->next;
			}
			if (!p) {// 插入节点的 exp 值是最小的,插在链表末尾
				s->next = q->next;
				q->next = s;
			}
		}
	}
	return OK;
}

//将两个多项式相加,线性表合并算法 
void PolynomialAdd(Polylist A, Polylist B) {
	Polylist p, q, tail, temp;
	float sum;
	// 令 p 和 q 分别指向 A 和 B 多项式链表的第一个结点 
	p = A->next;
	q = B->next;
	tail = A; // tail 指向多项式的尾结点 
	while (p && q) { // 当两个多项式均未扫描结束时 
		if (p->exp > q->exp) {
			// p 指向的多项式指数大于 q 的指数,将 p 结点加入到和多项式中 
			tail->next = p;
			tail = p;
			p = p->next;
		}
		else if (p->exp == q->exp) {
			// 若指数相等,则相应的系数相加 
			sum = p->coef + q->coef;
			if (sum != 0) {
				// 系数和非零,则系数和置入结点 p,p 加入到和多项式,
				// 释放结点 q,并将指针后移 
				p->coef = sum;
				tail->next = p;
				tail = p;
				p = p->next;
				temp = q; q = q->next; free(temp);
			}
			else {
				// 若系数和为零,则删除结点 p 与 q,并将指针指向下一个结点 
				temp = p; p = p->next; free(temp);
				temp = q; q = q->next; free(temp);
			}
		}
		else {
			//  p 指向的多项式指数小于 q 的指数,将 q 结点加入到和多项式中 
			tail->next = q;
			tail = q;
			q = q->next;
		}
	}
	if (p) {
		// 多项式 A 中还有剩余,将剩余的结点加入到和多项式中 
		tail->next = p;
	}
	else {
		// 多项式 B 中还有剩余,将剩余的结点加入到和多项式中 
		tail->next = q;
	}
	free(B); //释放 B 链表所占的内存 
}


//初始化多项式链表
void Init(Polylist& X) {
	X = (Polylist)malloc(sizeof(Polynode));
	X->next = NULL; // 将链表的头节点的 next 域置为空 
	X->exp = 32767; // 初始时头节点的 exp 域为无穷大 
	X->coef = 32767; // 初始时头节点的 coef 域为无穷大 
}

// 输出计算结果
void DisplayResult(Polylist A) {
	Polylist p, temp;
	p = A->next;
	printf("计算结果:");
	if (p == NULL) { // 处理为相加为 0 的情况 
		printf("0");
	}
	else
		while (p) {
			// 如果不是最后一个结点,则分别打印系数、未知元、指数、空格、加号、空格
			// 如果是最后一个结点 ,则分别打印系数、未知元、指数
			// 同平常书写一样,如果系数或指数为 1 则省略不打印,如果是常数项,则只打印常数 
			if (p->next != NULL && p->exp != 1 && p->coef != 1) {
				printf("%fx^%d + ", p->coef, p->exp);
			}
			else if (p->next != NULL && p->exp == 1 && p->coef != 1) {
				printf("%fx + ", p->coef);
			}
			else if (p->next != NULL && p->exp != 1 && p->coef == 1) {
				printf("x^%d + ", p->exp);
			}
			else if (p->next != NULL && p->exp == 1 && p->coef == 1) {
				printf("x + ");
			}
			else if (p->next != NULL && p->exp == 0) {
				printf("%f + ", p->coef);
			}
			else if (p->next == NULL && p->exp == 0) {
				printf("%f", p->coef);
			}
			else if (p->next == NULL && p->exp != 1 && p->coef != 1) {
				printf("%fx^%d", p->coef, p->exp);
			}
			else if (p->next == NULL && p->exp == 1 && p->coef != 1) {
				printf("%fx", p->coef);
			}
			else if (p->next == NULL && p->exp != 1 && p->coef == 1) {
				printf("x^%d", p->exp);
			}
			else if (p->next == NULL && p->exp == 1 && p->coef == 1) {
				printf("x");
			}
			temp = p;
			p = p->next;
			free(temp); // 依次释放每个节点的内存 
		}
	free(A); // 释放 A 节点 
	printf("\n");
}

// 指令输入与判断
int Input_judgefun(int function) {
	scanf("%d", &function);
	while (function < 0 || function > 2) {
		// 有效指令为 0、1、2,如菜单中所示 
		printf("输入指令有误!请重新输入:");
		scanf("%d", &function);
	}
	return function;
}

// 显示菜单
void Menu() {
	printf("\t\t\t\t\t欢迎使用一元稀疏多项式加法计算器!\n");
	printf("\t\t\t\t\t\t******菜单******\n");
	printf("\t\t\t\t\t\t*              *\n");
	printf("\t\t\t\t\t\t* 1.开始计算   *\n");
	printf("\t\t\t\t\t\t*              *\n");
	printf("\t\t\t\t\t\t* 2.关于我们   *\n");
	printf("\t\t\t\t\t\t*              *\n");
	printf("\t\t\t\t\t\t* 0.退出       *\n");
	printf("\t\t\t\t\t\t*              *\n");
	printf("\t\t\t\t\t\t****************\n");
	printf("请输入对应功能前的数字:");
}

// 关于我们
void AboutUs() {
	printf("开发者:Mr.Liu && Mr.Li\n");
	printf("更新时间:2020/7/5\n");
	printf("联系方式:3278469676 && 1498860407\n");
}

如有不足,请多指教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值