您的Push2 总是推到列表的前面(即头部)。
组合/添加时,需要一个追加到列表tail的推送。
另外,我认为你希望总和有 8x4 和 不 3x4 如你所说(即你的程序是正确的,除了顺序相反) 因为每个输入多项式都有一个x4 项。
此外,您的打印多项式函数不需要是递归的。
并且,不要转换malloc的结果
这是一个带有一些调试打印的重构版本。我为追加创建了第二个推送功能。忽略TERM [宏]——在我发现真正的问题之前,这是一次不完整的清晰尝试。
#include <stdio.h>
#include <stdlib.h>
typedef struct term {
int coef;
int exp;
struct term *next;
} term;
#ifdef DEBUG
#define dbgprt(_fmt...) \
printf(_fmt)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
typedef void (*pushfnc_p)(term **headRef, int coef, int exp);
void
Push2(term **headRef, int coef, int exp)
{
term *newNode = malloc(sizeof(*newNode));
if (coef == 0)
return;
newNode->coef = coef;
newNode->exp = exp;
newNode->next = *headRef;
*headRef = newNode;
}
void
Push2_tail(term **headRef, int coef, int exp)
{
term *newNode = malloc(sizeof(*newNode));
term *head = *headRef;
if (coef == 0)
return;
term *prev = NULL;
for (struct term *cur = head; cur != NULL; cur = cur->next)
prev = cur;
newNode->coef = coef;
newNode->exp = exp;
newNode->next = NULL;
if (prev != NULL)
prev->next = newNode;
else
head = newNode;
*headRef = head;
}
term *
addPolynomials2(term *h1, term *h2)
{
term *current1 = h1;
term *current2 = h2;
#if 0
pushfnc_p push = Push2;
#else
pushfnc_p push = Push2_tail;
#endif
term *new = NULL;
while (current1 && current2) {
dbgprt("add: DUAL current1=%dX%d current2=%dX%d\n",
current1->coef,current1->exp,
current2->coef,current2->exp);
if (current1->exp == current2->exp) {
dbgprt("add: SAME\n");
push(&new, (current1->coef + current2->coef), current1->exp);
current1 = current1->next;
current2 = current2->next;
continue;
}
if (current1->exp > current2->exp) {
dbgprt("add: CURR1\n");
push(&new, current1->coef, current1->exp);
current1 = current1->next;
continue;
}
dbgprt("add: CURR2\n");
push(&new, current2->coef, current2->exp);
current2 = current2->next;
}
while (current1) {
dbgprt("add: POST1 current1=%dX%d\n",
current1->coef,current1->exp);
push(&new, current1->coef, current1->exp);
current1 = current1->next;
}
while (current2) {
dbgprt("add: POST2 current2=%dX%d\n",
current2->coef,current2->exp);
push(&new, current2->coef, current2->exp);
current2 = current2->next;
}
return new;
}
void
printTerm(term *head)
{
printf("%dx%d ", head->coef, head->exp);
}
void
printPolynomial(term *head)
{
for (; head != NULL; head = head->next)
printTerm(head);
}
#define TERM(_coef,_exp) \
{ .coef = _coef, .exp = _exp },
void
addPolynomialsTest2(void)
{
term *head1 = NULL;
term *head2 = NULL;
term *new;
#if 1
int a[] = { 10, 0, 0, 5, 0, 3, 0, 5 };
int b[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
for (int i = sizeof(a) / sizeof(int) - 1; i >= 0; i--) {
Push2(&head1, a[i], b[i]);
}
int c[] = { 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int d[] = { 3, 0, 0, 0, 3, 0, 0, 3, -6 };
for (int i = sizeof(d) / sizeof(int) - 1; i >= 0; i--) {
Push2(&head2, d[i], c[i]);
}
#else
term a[] = {
TERM(10,7)
TERM(0,6)
TERM(0,5)
TERM(5,4)
TERM(0,3)
TERM(3,2)
TERM(0,5)
};
for (int i = sizeof(a) / sizeof(term) - 1; i >= 0; i--) {
term *t = &a[i];
Push2(&head1,t->coef,t->exp);
}
#endif
printf("F(x)= ");
printPolynomial(head2);
printf("\n");
printf("Q(x)= ");
printPolynomial(head1);
printf("\n");
printf("F(x) + Q(X)= ");
new = addPolynomials2(head1, head2);
printPolynomial(new);
printf("\n");
printf("\n");
}
int
main(void)
{
addPolynomialsTest2();
return 0;
}
这是程序输出:
F(x)= 3x8 3x4 3x1 -6x0
Q(x)= 10x7 5x4 3x2 5x0
F(x) + Q(X)= 3x8 10x7 8x4 3x2 3x1 -1x0
更新:
我尝试通过反向打印结果而不在末尾插入,但输出更奇怪知道为什么吗?
不完全确定。听起来像是两个错误使一个正确......见下文。
当创建多项式时,您的代码使用前推确实可以工作,但是,IMO,它有点复杂,因为您必须遍历数组以相反的顺序。
然而,添加函数确实需要push-to-tail。使用 push-to-front,添加将失败。因此,尝试以相反的顺序打印以“补偿”不正确的添加函数可能不是有效的修复方法。
因此,在原始代码中,您有两个输入多项式按从高到低的顺序 [如我们所愿],但 输出 多项式的顺序 颠倒了。
因此,如果您尝试将输出添加到其他内容(例如再次输入其中一个),它将中断。
因此,通过反向打印进行补偿不能解决问题。它仅用于打印。
实际上并不需要推到前面。我得到了TERM 宏工作。它使用push-to-tail并从0到N遍历数组[更容易理解]。
所以,这是,IMO,更干净一点:
#include <stdio.h>
#include <stdlib.h>
typedef struct term {
int coef;
int exp;
struct term *next;
} term;
#ifdef DEBUG
#define dbgprt(_fmt...) \
printf(_fmt)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
typedef void (*pushfnc_p)(term **headRef, int coef, int exp);
void
Push2(term **headRef, int coef, int exp)
{
term *newNode = malloc(sizeof(*newNode));
if (coef == 0)
return;
newNode->coef = coef;
newNode->exp = exp;
newNode->next = *headRef;
*headRef = newNode;
}
void
Push2_tail(term **headRef, int coef, int exp)
{
term *newNode = malloc(sizeof(*newNode));
term *head = *headRef;
if (coef == 0)
return;
term *prev = NULL;
for (struct term *cur = head; cur != NULL; cur = cur->next)
prev = cur;
newNode->coef = coef;
newNode->exp = exp;
newNode->next = NULL;
if (prev != NULL)
prev->next = newNode;
else
head = newNode;
*headRef = head;
}
term *
addPolynomials2(term *h1, term *h2)
{
term *current1 = h1;
term *current2 = h2;
#if 0
pushfnc_p push = Push2;
#else
pushfnc_p push = Push2_tail;
#endif
term *new = NULL;
while (current1 && current2) {
dbgprt("add: DUAL current1=%dX%d current2=%dX%d\n",
current1->coef,current1->exp,
current2->coef,current2->exp);
if (current1->exp == current2->exp) {
dbgprt("add: SAME\n");
push(&new, (current1->coef + current2->coef), current1->exp);
current1 = current1->next;
current2 = current2->next;
continue;
}
if (current1->exp > current2->exp) {
dbgprt("add: CURR1\n");
push(&new, current1->coef, current1->exp);
current1 = current1->next;
continue;
}
dbgprt("add: CURR2\n");
push(&new, current2->coef, current2->exp);
current2 = current2->next;
}
while (current1) {
dbgprt("add: POST1 current1=%dX%d\n",
current1->coef,current1->exp);
push(&new, current1->coef, current1->exp);
current1 = current1->next;
}
while (current2) {
dbgprt("add: POST2 current2=%dX%d\n",
current2->coef,current2->exp);
push(&new, current2->coef, current2->exp);
current2 = current2->next;
}
return new;
}
void
printTerm(term *head)
{
printf("%dx%d ", head->coef, head->exp);
}
void
printPolynomial(term *head)
{
for (; head != NULL; head = head->next)
printTerm(head);
}
#define TERM(_coef,_exp) \
{ .coef = _coef, .exp = _exp },
void
addPolynomialsTest2(void)
{
term *head1 = NULL;
term *head2 = NULL;
term *new;
#if 0
int a[] = { 10, 0, 0, 5, 0, 3, 0, 5 };
int b[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
for (int i = sizeof(a) / sizeof(int) - 1; i >= 0; i--) {
Push2(&head1, a[i], b[i]);
}
int c[] = { 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int d[] = { 3, 0, 0, 0, 3, 0, 0, 3, -6 };
for (int i = sizeof(d) / sizeof(int) - 1; i >= 0; i--) {
Push2(&head2, d[i], c[i]);
}
#else
term ab[] = {
TERM(10,7)
TERM(0,6)
TERM(0,5)
TERM(5,4)
TERM(0,3)
TERM(3,2)
TERM(0,5)
};
for (int i = 0; i < sizeof(ab) / sizeof(term); ++i) {
term *t = &ab[i];
Push2_tail(&head1,t->coef,t->exp);
}
term cd[] = {
TERM(3,8)
TERM(0,7)
TERM(0,6)
TERM(0,5)
TERM(3,4)
TERM(0,3)
TERM(0,2)
TERM(3,1)
TERM(-6,0)
};
for (int i = 0; i < sizeof(cd) / sizeof(term); ++i) {
term *t = &cd[i];
Push2_tail(&head2,t->coef,t->exp);
}
#endif
printf("F(x)= ");
printPolynomial(head2);
printf("\n");
printf("Q(x)= ");
printPolynomial(head1);
printf("\n");
printf("F(x) + Q(X)= ");
new = addPolynomials2(head1, head2);
printPolynomial(new);
printf("\n");
printf("\n");
}
int
main(void)
{
addPolynomialsTest2();
return 0;
}
这是一个有争议的问题,因为以相反的顺序构造输出是不正确的(即不这样做)。
但是,现在,我明白您为什么想要一个 递归 函数来打印多项式了。
要以 reverse 顺序打印,我认为该函数必须递归地打印 current 项 after呼唤自己。我还没有想到[或测试过]:
void
printTerm(term *head)
{
printf("%dx%d ", head->coef, head->exp);
}
void
printPolynomial(term *head)
{
if (head == 0)
return;
#if 0
printTerm(head);
printPolynomial(head->next);
#else
printPolynomial(head->next);
printTerm(head);
#endif
}
这可能修复结果多项式的打印。
但是,这样做会破坏两个输入多项式的打印。