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循环没法跳出,最后溢出了什么的。。