题目描述:
实现两个一元n次多项式的加法。例如P(A)=x+3x2-5x5+7,P(B)=2x2+6x3+x5-4x6,求P(A)+P(B)。
输入:每行是两个用空格隔开的整数m,n,分别代表多项式的系数和指数,以输入0 0作为结尾
输出:每次完成一个多项式的输入后,先输出该多项式;当第二个多项式输出完成后,下一行输出两个多项式输出的结果
(多项式打印的要求: 如果是第一项,不要打+号
//如果不是第一项,且系数为正数,要打加号
//如果系数为负数,系数自身带有符号
//如果系数为1,不用打系数
//系数为-1打印负号
//如果系数不为1或-1,打印系数
//如果指数为0,直接打系数不用打x^和指数
//如果系数是-1或1,需要打1出来,不能只打符号
//指数不为0
//打印x
//如果指数为1,不打指数,否则打指数)
这里对需要用到的函数进行说明:
(1)数字转换为字符串函数itoa
(2)字符串连接函数strcat
以两个字符串作为参数,把第2个字符串备份附加在第1个字符串末尾,并把拼接后形成的新的字符串作为第一个字符串,第二个字符串不变。
函数返回值 第一个字符串的地址
(3)字符串清空函数memset
memset(item,0,20);清空长20的字符串item
#include
#include
#include
typedef struct polynomial
{
int coefficient;//系数
int exp;//指数
struct polynomial *next;//指针域
}*Link,Node ; //link指向多项式的结构体指针 ,node结构体变量
void inputPoly(Link head);//从控制台堕入链表的函数
void print(Link head);
bool insert(Link head,int coefficient,int exp);//插入函数
void comlin2List(Link heada,Link headb,Link headab);//合并两个链表
void inputPoly(Link head)
{
int coefficient,exp;//系数和指数
printf("请输入系数和指数:");
scanf("%d %d",&coefficient,&exp);
while(coefficient!=0||exp!=0)
{
insert(head,coefficient,exp);//掉函数输入多项式
printf("请输入系数和指数");
scanf("%d %d",&coefficient,&exp);
}
}
bool insert(Link head,int coefficient,int exp)//保证指数是从大到小排列的
{
/*创建新节点*/
Link newNode;//node指针指向新创建的节点
Link q,p;//q,p两个节点一前一后
p = head->next;
q = head;//把q设为头节点,p为头结点的下一个
newNode = (Link)malloc(sizeof(Node));
newNode->coefficient = coefficient;
newNode->exp = exp;
// int *new;
// new=(int*) malloc(sizeof(int)); //不用int,直接用Node结构体变量
// new->coefficient=coefficient;//这样coefficient不在结构体内
// new->exp=exp;
newNode->next=NULL;///缺了这一句,新的节点数据就显示不出了,指针域next域为null
/*插入*/
if(p==NULL)//空表,插入第一个
{
q->next = newNode;
newNode->next = NULL;//到尾了,指针域赋空值
return true;
} //大于当前指数 ,插在p前q后
else if(exp>p->exp){
q->next=newNode;
newNode->next=p;
return true;
}//小于当前指数,向后移动指针(保持p,q一前一后)
else{
q=p;
p =p->next;//向后移动一位
}
}
/*打印链表多项式*/
void print(Link head) {
Link p; //指向链表要输出的结点
printf("多项式如下:\n");
p = head->next;
if (p == NULL) { //多项式为空的情况
printf("多项式为空\n");
return;
}
// 不是空表
char item[20] = ""; //要打印的当前多项式的一项
char number[7] = ""; //暂时存放系数转换成的字符串
bool isFirstItem = true;//标志是否为第一个节点
int flag = 0; //只要进入过系数非0的情况,flag=1,判断就为false了,也就是不是第一项
//打印节点
while (p != NULL) {
memset(item, 0, 20); //清空字符串item,清空长20的字符串
itoa(p->coefficient, number, 10);//欲转换的字符串数据:系数,number目标字符串地址,转换进制10
if (p->coefficient == 0) {//当为0时的判断非常容易出错,系数为0
if (flag == 0) {
isFirstItem = true; //如果第一项系数为0,移动指针,判断仍为true
p = p->next;
continue;
} else if (flag == 1) {//其他项系数为0,移动指针
p = p->next;
continue;
}
} else { //系数不为0
if (isFirstItem != true && p->coefficient > 0) {
strcat(item, "+");//字符串的拼接,当前系数不为第一项,输出数字和加号
}
if (p->coefficient == 1) {}//如果系数为1 ,则不用输出系数这块
else if (p->coefficient == -1) { //如果系数为-1,输出负号和数字
strcat(item, "-");
} else if (p->coefficient != 0) { //如果系数非0,输出
strcat(item, number);//输出系数和多项式那箱
}
if (p->exp == 1) { //如果指数为1
strcat(item, "x"); //输出系数和x
} else if (p->exp == 0) { //如果指数为0
if (p->coefficient == 1 || p->coefficient == -1)
strcat(item, "1");//且系数为1或-1时,任何数的0次幂都为1
} else { //如果指数为正常情况
strcat(item, "x^"); // 连接系数和x的指数
strcat(item, itoa(p->exp, number, 10)); //欲转换的字符串数据:指数,number目标字符串地址,转换进制10
}
flag = 1;
}
printf("%s", item); //打印当前节点代表的项
p = p->next;//指向下个结点
isFirstItem = false; //标志不是第一项了
}
printf("\n");
return;
}
/*合并链表函数 */
void combin2List(Link heada, Link headb, Link headab) {
Link pa, pb; //指向a,b链表和ab的指针
pa = heada->next;
pb = headb->next;
while (pa != NULL && pb != NULL) { //a,b链表都没有没有访问完毕
if (pa->exp > pb->exp) { //a的指数大于b的指数
insert(headab, pa->coefficient, pa->exp);//调用自定义函数insert()
pa = pa->next; //pa向后移一位
} else if (pa->exp < pb->exp) { //a的指数小于b
insert(headab, pb->coefficient, pb->exp); //调用
pb = pb->next; //pb向后移一位
} else if (pa->exp == pb->exp) { //a,b指数相同
int coefficient;
coefficient = pa->coefficient + pb->coefficient; //合并,合并后的系数为a,b之和
insert(headab, coefficient, pa->exp);
pa = pa->next;
pb = pb->next;
}
//如果指数a>指数b,a节点插入ab链表,a指针后移
//如果指数a<指数b,b节点插入ab链表,b指针后移
//如果指数a==指数b,a、b系数相加,插入ab链表,a、b指针后移
}
//如果a、b链表还有尾巴,将它加到ab链表后面
while (pa != NULL) {
insert(headab, pa->coefficient, pa->exp);
pa = pa->next;
}
while (pb != NULL) {
insert(headab, pb->coefficient, pb->exp);
pb = pb->next;
}
return;
}
/*清空链表函数*/
void clearLink(Link head) {
Link p, q;
if (head == NULL)
return;
q = head->next;
free(head); //释放head
while (q != NULL) {
p = q;
q = q->next;
free(p);
}
}
/*主函数*/
int main() {
Link headA, headB; //两个多项式的头指针
Link headAB;//合并后的多项式的头指针
/*链表的初始化*/
headA = (Link)malloc(sizeof(Node));
headA->next = NULL;
headB = (Link)malloc(sizeof(Node));
headB->next = NULL;
headAB = (Link)malloc(sizeof(Node));
headAB->next = NULL;
printf("请输入第一个多项式的系数和指数,以(0 0)结束:\n");
inputPoly(headA);
printf("第一个");
print(headA);
printf("请输入第二个多项式的系数和指数,以(0 0)结束:\n");
inputPoly(headB);
printf("第二个");
print(headB);
combin2List(headA, headB, headAB);
printf("合并后");
print(headAB);
clearLink(headA);
clearLink(headB);
clearLink(headAB);
return 0;
}