如何解决C中包含3个变量的多项式加法
这是给我们的编码练习。我见过很多例子,但它们大多只使用一个变量 x
。对于这个,两个多项式最多可以包含 3 个变量。
让我解释输入。第一行表示第一个多项式的项数(非零系数)n
。接下来的 n
行表示形式为 x exponent
y exponent
z exponent
coefficient
的第一个多项式的每一项。示例:4x⁵y⁴z²
将是 5 4 2 4
。下一行是同样的事情,但它将用于第二个多项式。我们将返回结果总和并按规范顺序逐行打印它们。系数是一个可以有符号或无符号的实数。我会提供一个测试用例。
我已经研究并制定了所有任务。事实上,我将提供的测试用例可以通过我的代码正确回答。我的问题是,在某些隐藏情况下,我的代码给出了错误的答案,而且我开始认为我的算法遗漏了一些东西。
无论如何,这是我的全部代码。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
struct Node
{
float coeff;
int powX;
int powY;
int powZ;
struct Node* next;
};
void readPolynomial(struct Node** poly)
{
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
*poly = temp;
int terms;
fscanf(stdin,"%d",&terms);
getchar();
char entry[999999];
char *splitter;
for(int i = 0; i < terms; i++)
{
fgets(entry,sizeof(entry),stdin);
splitter = strtok(entry," ");
temp->powX = atoi(splitter);
splitter = strtok(NULL," ");
temp->powY = atoi(splitter);
splitter = strtok(NULL," ");
temp->powZ = atoi(splitter);
splitter = strtok(NULL," ");
temp->coeff = atof(splitter);
temp->next = NULL;
if(i != terms-1)
{
temp->next = (struct Node*)malloc(sizeof(struct Node));
temp = temp->next;
temp->next = NULL;
}
}
}
int compareTerms(const struct Node *a,const struct Node *b)
{
int cmp;
cmp = (a->powX > b->powX) - (a->powX < b->powX);
if (cmp != 0) {
return cmp;
}
cmp = (a->powY > b->powY) - (a->powY < b->powY);
if (cmp != 0) {
return cmp;
}
cmp = (a->powZ > b->powZ) - (a->powZ < b->powZ);
return cmp;
}
void sortPolynomialTerms(struct Node **poly)
{
struct Node *head;
unsigned int sublen;
head = *poly;
if (!head) {
return;
}
sublen = 1;
while (1) {
struct Node *tail;
struct Node *p;
struct Node *q;
struct Node *e;
unsigned int plen;
unsigned int qlen;
unsigned int merges;
unsigned int i;
p = head;
head = NULL;
tail = NULL;
merges = 0;
while (p) {
merges++;
q = p;
plen = 0;
for (i = 0; i < sublen; i++) {
plen++;
q = q->next;
if (!q) {
break;
}
}
qlen = plen;
while (plen || (qlen && q)) {
if (!plen || (qlen && q && compareTerms(p,q) < 0)) {
e = q;
q = q->next;
qlen--;
} else {
e = p;
p = p->next;
plen--;
}
if (tail) {
tail->next = e;
} else {
head = e;
}
tail = e;
}
p = q;
}
tail->next = NULL;
if (merges <= 1) {
break;
}
sublen *= 2;
}
*poly = head;
}
void printPolynomial(const struct Node *poly)
{
while (poly)
{
if(poly->coeff != 0)
{
printf("%d %d %d %.3f\n",poly->powX,poly->powY,poly->powZ,poly->coeff);
}
poly = poly->next;
}
}
void canonicalPolynomial(struct Node **poly)
{
sortPolynomialTerms(poly);
printPolynomial(*poly);
}
void addPolynomials(struct Node** result,struct Node* first,struct Node* second)
{
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->next = NULL;
*result = temp;
while(first && second)
{
if(compareTerms(first,second) < 0)
{
temp->coeff = second->coeff;
temp->powX = second->powX;
temp->powY = second->powY;
temp->powZ = second->powZ;
second = second->next;
}
else if(compareTerms(first,second) > 0)
{
temp->coeff = first->coeff;
temp->powX = first->powX;
temp->powY = first->powY;
temp->powZ = first->powZ;
first = first->next;
}
else
{
temp->coeff = first->coeff + second->coeff;
temp->powX = first->powX;
temp->powY = first->powY;
temp->powZ = first->powZ;
first = first->next;
second = second->next;
}
if(first && second)
{
temp->next = (struct Node*)malloc(sizeof(struct Node));
temp = temp->next;
temp->next = NULL;
}
}
while(first || second)
{
temp->next = (struct Node*)malloc(sizeof(struct Node));
temp = temp->next;
temp->next = NULL;
if(second)
{
temp->coeff = second->coeff;
temp->powX = second->powX;
temp->powY = second->powY;
temp->powZ = second->powZ;
second = second->next;
}
else if(first)
{
temp->coeff = first->coeff;
temp->powX = first->powX;
temp->powY = first->powY;
temp->powZ = first->powZ;
first = first->next;
}
}
}
int main()
{
struct Node* first = NULL;
struct Node* second = NULL;
struct Node* result = NULL;
readPolynomial(&first);
readPolynomial(&second);
addPolynomials(&result,first,second);
canonicalPolynomial(&result);
return 0;
}
测试用例:
3
1 6 0 -7
0 7 0 -6
7 0 0 1
5
1 0 1 9
0 7 0 -2
5 3 2 4
1 2 3 4
1 3 0 3
预期输出:
7 0 0 1.000
5 3 2 4.000
1 6 0 -7.000
1 3 0 3.000
1 2 3 4.000
1 0 1 9.000
0 7 0 -8.000
说明:
x⁷ - 7xy⁶ - 6y⁷
+ 4x⁵y³z² + 3xy³ + 4xy²z³ + 9xz - 2y⁷
= x⁷ + 4x⁵y⁴z² - 7xy⁶ + 3xy³ + 4xy²z³ + 9xz - 8y⁷
最初,我认为我的 addPolynomial
函数存在问题。我刚刚从一个变量的多项式加法的示例代码中删除了它并进行了一些修改。
checkTerms
遍历整个 Polynomial 并添加相邻项(如果它们的度数相同)。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
struct Node
{
float coeff;
int powX;
int powY;
int powZ;
struct Node* next;
};
void readPolynomial(struct Node** poly)
{
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
*poly = temp;
int terms;
fscanf(stdin,&terms);
getchar();
char entry[30];
char *splitter;
for(int i = 0; i < terms; i++)
{
fgets(entry,poly->coeff);
}
poly = poly->next;
}
}
void canonicalPolynomial(struct Node **poly)
{
sortPolynomialTerms(poly);
printPolynomial(*poly);
}
void checkTerms(struct Node* poly)
{
while(poly)
{
if(poly->next != NULL)
{
if(compareTerms(poly,poly->next) == 0)
{
poly->coeff = poly->coeff + poly->next->coeff;
poly->next = poly->next->next;
}
}
poly = poly->next;
}
}
void addPolynomials(struct Node** result,second) > 0)
{
temp->coeff = first->coeff;
temp->powX = first->powX;
temp->powY = first->powY;
temp->powZ = first->powZ;
first = first->next;
}
else
{
temp->coeff = first->coeff + second->coeff;
temp->powX = first->powX;
temp->powY = first->powY;
temp->powZ = first->powZ;
first = first->next;
second = second->next;
}
if(first && second)
{
temp->next = (struct Node*)malloc(sizeof(struct Node));
temp = temp->next;
temp->next = NULL;
}
}
while(first || second)
{
temp->next = (struct Node*)malloc(sizeof(struct Node));
temp = temp->next;
temp->next = NULL;
if(second)
{
temp->coeff = second->coeff;
temp->powX = second->powX;
temp->powY = second->powY;
temp->powZ = second->powZ;
second = second->next;
}
else if(first)
{
temp->coeff = first->coeff;
temp->powX = first->powX;
temp->powY = first->powY;
temp->powZ = first->powZ;
first = first->next;
}
}
}
int main()
{
struct Node* first = NULL;
struct Node* second = NULL;
struct Node* result = NULL;
readPolynomial(&first);
readPolynomial(&second);
sortPolynomialTerms(&first);
checkTerms(&first);
sortPolynomialTerms(&second);
checkTerms(&second);
addPolynomials(&result,second);
canonicalPolynomial(&result);
return 0;
}
解决方法
没有必要使用列表。由于引入的多项式的大小是预先给定的,因此可以分配足够的。接下来使用 realloc()
加载另一个多项式。
零系数的定义有问题。应指定精度。我假设它是 0。
问题可以分阶段解决:
- 读取第一个多项式的大小
- 分配数组
- 加载第一个多项式
- 读取第二个多边形的大小
- 重新分配数组以拟合两个多项式
- 读取第二个多边形
- 对项进行排序以确保所有具有相同指数的项都是相邻项
- 累积具有相同指数的连续项块
- 打印结果
代码。省略了错误处理。
#include <stdio.h>
#include <stdlib.h>
struct term {
int x,y,z;
double coef;
};
struct term load_term() {
struct term T;
scanf("%d %d %d %lf",&T.x,&T.y,&T.z,&T.coef);
return T;
}
int term_cmp(const void *a_,const void *b_) {
const struct term *a = a_,*b = b_;
if (a->x != b->x) return b->x - a->x;
if (a->y != b->y) return b->y - a->y;
return b->z - a->z;
}
int main() {
int n = 0,m;
// load first polynomial
scanf("%d",&m);
struct term *P = malloc(m * sizeof *P);
while (m--) P[n++] = load_term();
// load second polynomial
scanf("%d",&m);
P = realloc(P,(n + m) * sizeof *P);
while (m--) P[n++] = load_term();
// sort by x,z exponents
qsort(P,n,sizeof *P,term_cmp);
// merge
int n2 = 0;
for (int i = 0; i < n; ++i) {
if (n2 > 0 && term_cmp(&P[n2 - 1],&P[i]) == 0) {
// as long as exponents are the same as the last
// accumulate coefficients to the last term
P[n2 - 1].coef += P[i].coef;
} else {
// start a new term
P[n2++] = P[i];
}
}
// print accumulated polynomial of size `n2`
for (int i = 0; i < n2; ++i)
if (P[i].coef != 0)
printf("%d %d %d %.3lf\n",P[i].x,P[i].y,P[i].z,P[i].coef);
free(P);
}
,
我认为它可以以非常简洁的方式编写。你能试试这个代码吗? 我的方法与@tstanisl 的方法非常相似。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<float.h>
static int comparefn(const void *a,const void *b)
{
const double *l= (const double *) a;
const double *r= (const double *) b;
for(int i= 0; i< 3; ++i) {
if(l[i]< r[i]) { return -1; }
if(l[i]> r[i]) { return 1; }
if(l[0]== r[0]) { continue; }
}
return 0;
}
double *data= NULL;
int main(int argc,char *argv[])
{
int n1= 0;
scanf("%d",&n1);
data= malloc(sizeof(double)* n1* 4);
int i= 0;
for(; i< n1; ++i) {
scanf("%lf %lf %lf %lf",data+ i* 4,data+ i* 4+ 1,data+ i* 4+ 2,data+ i* 4+ 3);
}
int n2= 0;
scanf("%d",&n2);
data= realloc(data,sizeof(double)* (n1+ n2)* 4);
for(; i< n1+ n2; ++i) {
scanf("%lf %lf %lf %lf",data+ i* 4+ 3);
}
qsort(data,((size_t) (n1+ n2)),sizeof(double)* 4,&comparefn);
for(i= 1; i< n1+ n2; ++i) {
if(0== comparefn(data+ i* 4,data+ (i- 1)* 4)) {
data[i* 4+ 3]+= data[(i- 1)* 4+ 3]; data[(i- 1)* 4+ 3]= 0.0;
}
}
for(i= n1+ n2- 1; i> -1; --i) {
if(fabs(data[i* 4+ 3])> DBL_EPSILON) {
printf("%g %g %g %.3lf\n",data[i* 4],data[i* 4+ 1],data[i* 4+ 2],data[i* 4+ 3]);
}
}
if(NULL!= data) {
free(data);
data= NULL;
}
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。