lemon3 发表于 2018-12-24 10:42:03

Croper 发表于 2018-12-23 23:57
我这儿是没有问题的。。。你那是什么破编译器啊。。。。把if(!b)改成if(b==false)试试吧。。
另外自己也思 ...

我刚刚调试了一下,发现multiplication这个函数没有产生作用,它里面的p3没有变,一直是一个乱序的值。

Croper 发表于 2018-12-24 14:08:57

lemon3 发表于 2018-12-24 10:42
我刚刚调试了一下,发现multiplication这个函数没有产生作用,它里面的p3没有变,一直是一个乱序的值。

p3 = new NODE;改成p3 = (NODE*) malloc(sizeof(NODE));了么

lemon3 发表于 2018-12-24 14:23:22

嗯这儿改了

lemon3 发表于 2018-12-24 14:24:03

#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef int bool;
typedef struct node
{
      int    coef, exp;
      struct node*next;
} NODE;

NODE * multiplication(NODE *, NODE *);
void input(NODE *);
void output(NODE *);

NODE* Link(NODE* p,int i)   //输入头节点,返回第i个节点,i从0算起
{
        int j;
      for (j = 0; j <= i; j++)
      {
                p = p->next;
                if (p == NULL) return NULL;
      }
      return p;
}
int Length(NODE* p)      //输入头节点,返回长度,
{
      int j=0;
      while (p->next != NULL)
      {
                j++;
                p = p->next;

      }
      return j;
}

void Append(NODE* p, int coef0, int exp0)//为一个节点添加后继并重新将指针指向后继,
{
      p->next = (NODE*)malloc(sizeof(NODE));
      p = p->next;
      p->coef = coef0;
      p->exp = exp0;
      p->next=NULL;
}

void DeleteLinklist(NODE* head)//删除链表
{
      NODE *pPre;
      while (head != NULL)
      {
                pPre = head;
                head = head->next;
                free(pPre);
      }
}

NODE * multiplication(NODE *p1, NODE *p2)   //乘法运算
{
      NODE* ans,*p3;
      NODE* Temp1,* Temp2;
      p3 =(NODE*)malloc(sizeof(NODE));   //新建链表p3
      ans = p3;
                int i,j;          //ans指向p3的头节点,用于返回
      int len = Length(p1) + Length(p2)-1;    //p3的最高次项=两链表最高次项相加
      for (i = 0; i < len; i++)         //依次填充p3的每一项
      {
                Append(p3, 0, i);
                for (j = 0; j <= i; j++)
                {
                        Temp1 = Link(p1,j);            
                        Temp2 = Link(p2, i - j);
                        if ((Temp1!=NULL)&&(Temp2!=NULL)) p3->coef += (Temp1->coef*Temp2->coef);
                }
      }
      return ans;
}

void input(NODE * p)   //输入头节点,读取并储存于链表中
{
      int a, b;
      int i = 0;

      rewind(stdin);
      while(scanf_s("<%d,%d>,", &a, &b))    //读取一项,并将值暂时储存于a和b中
      {
                for (i; i < b; i++) Append(p, 0, i);   //延长链表,直到指数=b
                Append(p, a, b);                     //赋值
                i++;
      }

}

void output(NODE * head)
{
      bool b = false;                                    //储存是否已产生有效输出
      while (head->next != NULL)
      {
                head = head->next;
                if (head->coef != 0)
                {
                        b = true;                                           //如果任意一项系数不为0,即产生了有效输出
                        printf("<%d,%d>,", head->coef, head->exp);
                }
      }
      if (!b) printf("<0,0>,");                                 //如果没有产生有效输出,说明这是个0多项式,输出<0,0>
      printf("\n");
}

int main()
{
      int i;
      NODE * head1, *head2, *head3;

      head1 = (NODE *)malloc(sizeof(NODE));
      input(head1);

      head2 = (NODE *)malloc(sizeof(NODE));
      input(head2);

      head3 = multiplication(head1, head2);

      output(head3);
      
      DeleteLinklist(head1);
      DeleteLinklist(head2);
      DeleteLinklist(head3);
      return 0;
}

lemon3 发表于 2018-12-24 14:24:37

我用Dev调试观察到p3一直就没变过

lemon3 发表于 2018-12-24 14:56:53

Croper 发表于 2018-12-23 23:57
我这儿是没有问题的。。。你那是什么破编译器啊。。。。把if(!b)改成if(b==false)试试吧。。
另外自己也思 ...

我在NODE*Link这开始设置断点调试,发现输入的值没有存到p3里面去,几步之后直接跳到结尾曲了

lemon3 发表于 2018-12-24 14:58:23

lemon3 发表于 2018-12-24 14:56
我在NODE*Link这开始设置断点调试,发现输入的值没有存到p3里面去,几步之后直接跳到结尾曲了

你能大致讲一下multiplication这里的主要的思想吗,我有点没明白Temp1(p,i),和Temp2(p,i-j)这里的具体的意义。

Croper 发表于 2018-12-24 19:27:08

本帖最后由 Croper 于 2018-12-24 19:37 编辑

NODE * multiplication(NODE *p1, NODE *p2)   //乘法运算
{
        NODE* ans, *p3;
        NODE* Temp1, *Temp2;
        int i, j;
        p3 = (NODE*)malloc(sizeof(NODE));         //新建链表p3
        ans = p3;                                             //ans指向p3的头节点,用于返回      
        int len = Length(p1) + Length(p2) - 1;                           //设有两多项式A,B,它们的积为C;
                                                                                          //且A=a*x^0+a*x^1+...a*x^m    B=b*x^0+1*x^1+...+b*x^n
                                                                                          //则C=c*x^0+c*x^1+....c*x^(m+n);   <==这就是int len = Length(p1) + Length(p2) - 1;的原因       
        for (i = 0; i < len; i++)                                                 //其中c=a*b+a*b+...a*b 这里,Temp1->coef*Temp2->coef即为a*b                                       
        {
                Append(p3, 0, i);
                for (j = 0; j <= i; j++)                                       
                {
                        Temp1 = Link(p1, j);
                        Temp2 = Link(p2, i - j);
                        if ((Temp1 != NULL) && (Temp2 != NULL)) p3->coef += (Temp1->coef*Temp2->coef);
                }
        }
        return ans;
}

lemon3 发表于 2018-12-24 19:38:55

Croper 发表于 2018-12-24 19:27


我想问一句,这里可能有的次数是没有的,你有考虑吗,我看你的就是从次数为0到次数为最高次

Croper 发表于 2018-12-24 19:43:20

lemon3 发表于 2018-12-24 19:38
我想问一句,这里可能有的次数是没有的,你有考虑吗,我看你的就是从次数为0到次数为最高次

首先,读取的时候会把
<1,0>,<1,5>读取为<1,0>,<0,1>,<0,2>,<0,3>,<0,4>,<1,5>的形式,保证了在链表中次数是连续的,第n项的值次数即为n-1;

其次。。你认为if ((Temp1 != NULL) && (Temp2 != NULL)) 是干什么的。。?

lemon3 发表于 2018-12-24 19:48:40

lemon3 发表于 2018-12-24 14:24
#include
#include
#define true 1


发现一个问题,就是,你的Append里面的i是次数对吧,但是你的Link里面又是找的第i个或者第i-j个元素的系数,那这样的系数和次数就不对应了啊!!!比如说<1,3>和<2,3>,开始运行程序,你的Append次数现在是i=0,然后你找到了两个序列各自的第一个元素,两个的系数相乘,为2,但是你的次数现在不是6,而是0,对吗?!

Croper 发表于 2018-12-24 20:50:47

lemon3 发表于 2018-12-24 19:48
发现一个问题,就是,你的Append里面的i是次数对吧,但是你的Link里面又是找的第i个或者第i-j个元素的系 ...

你看下input函数,不会读出单独的<1,3>,输入的<1,3>会被读取为有四个节点的链表<0,0><0,1><0,2>,<1,3>同<2,3>=><0,0>,<0,1><0,2><2,3>
i为0时找到第一个元素,系数相乘 0*0=0;结果为<0,0>,没有问题

lemon3 发表于 2018-12-24 22:25:45

嗯对,我看到了,那现在我的编译器就是过不了,你的可以吗?

lemon3 发表于 2018-12-24 22:26:32

Croper 发表于 2018-12-24 20:50
你看下input函数,不会读出单独的,输入的会被读取为有四个节点的链表,同=>,
i为0时找到第一个元素,系 ...

但是每次输出都是<0,0>,你的编译器不是吗?

Croper 发表于 2018-12-24 23:20:28

我试了好几个例子,包括你给的题目,都是没问题的

Croper 发表于 2018-12-24 23:40:22

你看看是multiplication有问题还是input没有赋值成功,是不是不支持scanf_s什么的
不支持的话换scanf,我这边是因为vs不支持scanf了

lemon3 发表于 2018-12-25 00:59:25

嗯,就是这样,我改成scanf还是这样

Croper 发表于 2018-12-25 01:34:38

得,你说下你用的什么编译器Dev什么版本的,我调试成功再给你得了

Croper 发表于 2018-12-25 01:44:57

14.23s.....
嗯。。我大概知道怎么回事了
你把input函数改成这样void input(NODE * p)
{
        int a, b;
        int i = 0;
        int p;

        rewind(stdin);
        p = scanf("<%d,%d>,", &a, &b);
        printf("%d ", p);
        while (p)
        {
                       
                for (i; i < b; i++) Append(p, 0, i);
                Append(p, a, b);
                i++;
                p = scanf("<%d,%d>,", &a, &b);
                printf("%d ", p);
        }

}
运行一次,把结果发过来

Croper 发表于 2018-12-25 01:46:18

我猜多半是scanf返回值的问题。。while循环没法跳出,最后溢出了什么的。。
页: 1 [2] 3
查看完整版本: 一元多项式相加问题(C语言实现数据结构)