浙江大学MooC数据结构OJ——线性结构

        此刻的心情是无比喜悦的,可能这并不是一道超级难的OJ,但是想想过去的24小时,吃饭睡觉都在想它,所以写这篇来激励自己,主要还是记录这一刻,而且我好像第一次真正意义上的用结构和结构指针来写程序,确实体会到了其方便又复杂的调试过程,怎么说呢,孰能生巧,加油吧,少年!!!

线性结构1 一元多项式的乘法与加法运算 

设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0

输入样例:

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

输出样例:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0

有几个重要的点:

  • 合并同类项时可能出现抵消,系数为0不用输出

  • 0多项式很特殊,也不用输出

  • 还有常数项,按照意思,即使系数为0,也要输出

  • 。。。

CODE:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct mNode *Node;
typedef struct mNode
{
 int a;//系数
 int e;//指数
 Node next;//指针
}N;
 
Node read();
Node multiple(Node L1, Node L2);
Node add(Node L1, Node L2);
Node reverse(Node L);
void print(Node L);
 
int main()
{
 Node L1, L2,L;
 //printf("in main\n");
 L1=read();
 L2=read();
 //printf("return main\n");
 
 L=multiple(L1, L2);
 //printf("return multiple\n");
 print(L);
 //printf("return print1\n");
 L=add(L1, L2);
 //printf("return add\n");
 print(L);
 //printf("return print2\n");
 
 /*{
  while (L1->next!=NULL)
  {
   L1 = L1->next;
   printf("\t%d\t%d\n", L1->a, L1->e);
  }
 }*/
 free(L1);
 free(L2);
 free(L);
 return 0;
}
 
Node read()
{
 //printf("in read\n");
 int n;
 int i;
 Node head = (Node)malloc(sizeof(N));
 head->next = NULL;
 Node body;
 scanf_s("%d", &n);
 for (i = 0; i < n; i++)
 {
  body=(Node)malloc(sizeof(N));
  scanf_s("%d", &body->a);
  scanf_s("%d", &body->e);
  body->next = head->next;
  head->next = body;
 }
 return reverse(head);
}
 
Node multiple(Node L1, Node L2)
{
 //printf("in multiple\n");
 Node sum = (Node)malloc(sizeof(N));
 sum->next = NULL;
 Node body;
 Node temp;
 L1 = L1->next;
 L2 = L2->next;
 while(L1 != NULL)
 {
  if (L1->a != 0)
  {
   Node L = (Node)malloc(sizeof(N));
   L->next = NULL;
   temp = L2;
   while (temp != NULL)
   {
    body = (Node)malloc(sizeof(N));
    body->a = L1->a*temp->a;
    body->e = L1->e + temp->e;
    body->next = L->next;
    L->next = body;
    temp = temp->next;
   }
   L = reverse(L);
   sum = add(sum, L);
  }
  L1 = L1->next;
 }
 return sum;
}
 
Node add(Node L1, Node L2)
{
 //printf("in add\n");
 Node L = (Node)malloc(sizeof(N));
 L->next = NULL;
 Node body;
 L1 = L1->next;
 L2 = L2->next;
 while (L1 != NULL && L2 != NULL)
 {
  body = (Node)malloc(sizeof(N));
  if (L1->e == L2->e)
  {
   if(L1->a + L2->a!=0)
   {
    body->e = L1->e;
    body->a = L1->a + L2->a;
    body->next = L->next;
    L->next = body;
   }
   L1 = L1->next;
   L2 = L2->next;
  }
  else if(L1->e > L2->e)
  {
   body->e = L1->e;
   body->a = L1->a;
   L1 = L1->next;
   body->next = L->next;
   L->next = body;
  }
  else
  {
   body->e = L2->e;
   body->a = L2->a;
   L2 = L2->next;
   body->next = L->next;
   L->next = body;
  }
 }
 if (L1 != NULL)
 {
  do{
   body = (Node)malloc(sizeof(N));
   body->e = L1->e;
   body->a = L1->a;
   body->next = L->next;
   L->next = body;
   L1 = L1->next;
  } while(L1!=NULL);
 }
 if (L2 != NULL)
 {
  do {
   body = (Node)malloc(sizeof(N));
   body->e = L2->e;
   body->a = L2->a;
   body->next = L->next;
   L->next = body;
   L2 = L2->next;
  } while (L2 != NULL);
 }
 return reverse(L);
}

/****************** 
 由于我采用的链表连接方式使阶数从小往大了 
 实现的是从大到小
******************/ 
Node reverse(Node L)
{
 Node head = (Node)malloc(sizeof(N));
 head->next = NULL;
 Node body;
 L = L->next;
 if (L != NULL)
 {
  do
  {
   body = (Node)malloc(sizeof(N));
   body->a = L->a;
   body->e = L->e;
   body->next = head->next;
   head->next = body;
   L = L->next;
  } while (L != NULL);
 }
 return head;
}
 
void print(Node L)
{
 //printf("in print\n");
 int flag = 1;
 while(L->next!=NULL)
 {
  L = L->next;
  if ((L->a == 0 && L->e == 0)||(L->a != 0))
  {
   if (flag)
   {
    printf("%d %d", L->a, L->e);
    flag = 0;
   }
   else
   {
    printf(" %d %d", L->a, L->e);
   }
  }
 }
 if (flag)
 {
  printf("0 0");
 }
 printf("\n");
}

转载于:https://my.oschina.net/fchen24/blog/662418

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值