鱼C论坛

 找回密码
 立即注册
楼主: lemon3

[已解决]一元多项式相加问题(C语言实现数据结构)

[复制链接]
 楼主| 发表于 2018-12-24 10:42:03 | 显示全部楼层
Croper 发表于 2018-12-23 23:57
我这儿是没有问题的。。。你那是什么破编译器啊。。。。把if(!b)改成if(b==false)试试吧。。
另外自己也思 ...

我刚刚调试了一下,发现multiplication这个函数没有产生作用,它里面的p3没有变,一直是一个乱序的值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-24 14:08:57 | 显示全部楼层
lemon3 发表于 2018-12-24 10:42
我刚刚调试了一下,发现multiplication这个函数没有产生作用,它里面的p3没有变,一直是一个乱序的值。
p3 = new NODE;  
改成
p3 = (NODE*) malloc(sizeof(NODE));
了么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-24 14:23:22 | 显示全部楼层
嗯这儿改了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-24 14:24:37 | 显示全部楼层
我用Dev调试观察到p3一直就没变过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

我在NODE*Link这开始设置断点调试,发现输入的值没有存到p3里面去,几步之后直接跳到结尾曲了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你能大致讲一下multiplication这里的主要的思想吗,我有点没明白Temp1(p,i),和Temp2(p,i-j)这里的具体的意义。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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[0]*x^0+a[1]*x^1+...a[m]*x^m    B=b[0]*x^0+[b]1*x^1+...+b[n]*x^n
                                                                                          //则C=c[0]*x^0+c[1]*x^1+....c[m+n]*x^(m+n);   <==这就是int len = Length(p1) + Length(p2) - 1;的原因        
        for (i = 0; i < len; i++)                                                 //其中c[i]=a[0]*b[i]+a[1]*b[i-1]+...a[i]*b[0] 这里,Temp1->coef*Temp2->coef即为a[i-j]*b[j]                                        
        {
                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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-24 19:38:55 | 显示全部楼层

我想问一句,这里可能有的次数是没有的,你有考虑吗,我看你的就是从次数为0到次数为最高次
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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)) 是干什么的。。?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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,对吗?!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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>,没有问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-24 22:25:45 | 显示全部楼层
嗯对,我看到了,那现在我的编译器就是过不了,你的可以吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

但是每次输出都是<0,0>,你的编译器不是吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-24 23:20:28 | 显示全部楼层
我试了好几个例子,包括你给的题目,都是没问题的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-24 23:40:22 | 显示全部楼层
你看看是multiplication有问题还是input没有赋值成功,是不是不支持scanf_s什么的
不支持的话换scanf,我这边是因为vs不支持scanf了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-25 00:59:25 | 显示全部楼层
嗯,就是这样,我改成scanf还是这样
youwu.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-25 01:34:38 | 显示全部楼层
得,你说下你用的什么编译器Dev什么版本的,我调试成功再给你得了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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);
        }

}
运行一次,把结果发过来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-25 01:46:18 | 显示全部楼层
我猜多半是scanf返回值的问题。。while循环没法跳出,最后溢出了什么的。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 02:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表