一元多项式的相加,小白之作,只是简单的实现了一元N次多项式的相加(相乘的话都是差不多的原理,就没有想写的欲望了,摊手)。(只是记录,没有任何教学意义)
其实刚开始是使用数组实现的,但是感觉数组味道还是太浓了,和链表不太搭边,于是开始用真正的链表来实践,因为还要上课,所以断断续续写了3天,刚开始是没想写这么多的,结果发现实现一个功能就要先得到另一个数据,这就又要写一个函数来实现,所以写到最后子函数暴多还乱的离谱,最后也就是到可以让结果按指数由大到小的排列方式输出,同类项也没有合并,而且最致命的就是:两个多项式的最小指数必须相同,也是懒得写这个功能了,在文章中解释吧。
struct List
{
int factor;
int exponent;
struct List* next;
};
这是链表定义段,我发现如果typedef 成*List,然后用*List 来定义之后的函数的话,函数会出现巨多莫名奇妙的错误,但是书上又是这样教的,所以也是不明所以不敢用。
void intialization(struct List** polynomial)//初始化一个多项式;
{
int count, f, e;
printf("Please enter a polynomial number of items:");//需要输入多项式一共有多少项;
scanf_s("%d", &count);
for (int i = 1; i <= count; i++)
{
printf("Please enter factor and exponent for %dth\n", i);
scanf_s("%d%d", &f, &e);
insertNode(polynomial, f, e);//f是系数,e是指数,insertNode是一个插入函数;
}
}
新建链表使用。
struct List* Apoly = NULL;
intialization(&Apoly);
定义一般是这样的(主要是全自动新建链表对我来说错误太多了,直接放弃):
void insertNode(struct List** last, int ratio, int chara)//在链表最后插入系数和指数;
{
struct List* substitute = (*last);
struct List* new_Node = (struct List*)malloc(sizeof(struct List));
new_Node->factor = ratio;
new_Node->exponent = chara;
new_Node->next = NULL;
if ((*last) == NULL)
{
(*last) = new_Node;
return;
}
while (substitute->next != NULL)
substitute = substitute->next;
substitute->next = new_Node;
}
这是插入函数,其中用到了指针的指针,当时没有指针的指针概念,断点插的头都麻了也不知道为啥值进不去,后来还是找了个群问了大佬,大佬给我推荐了个网站,就说让我照着敲,才一点点琢磨明白的。(巨菜无比)
void collate(struct List** head_ref)//让多项式根据指数由大到小排列;
{
struct List* stroke = (*head_ref);
struct List* context = (*head_ref);
struct List* coincidence = NULL;
int count = Listlength(stroke);//通过链表长度确定循环次数;
int bigflag, flagbig;
while (count--)
{
int position;
bigflag = context->exponent;//指数;
flagbig = context->factor;//系数;
for (stroke = context; stroke != NULL; stroke = stroke->next)
{
if (stroke->exponent > bigflag)//如果发现系数大的,替换之;
{
bigflag = stroke->exponent;
flagbig = stroke->factor;
}
}
position=searchNode(context, bigflag);//找到那个最大指数的节点位置;
insertNode(&coincidence, flagbig, bigflag);//插入最大指数和其系数;
deletNode(&context, position);//删除那个节点,然后继续循环;
}
(*head_ref) = coincidence;//赋给头节点;
}
总觉得我这个方法巨笨无比,用了巨多函数,相当于新建了一个节点来一个一个放入最大指数的项,但是我也没看别人怎么做的,我也就能想到这了。
void deletNode(struct List** head_ref, int position)//删除position上的节点;
{
if ((*head_ref) == NULL)
return;
struct List* temp = (*head_ref);
struct List* ereas = (*head_ref);
if (position == 0)
{
(*head_ref) = (*head_ref)->next;
free(ereas);
return;
}
else
while (position--)
{
temp = ereas;
ereas=ereas->next;
}
temp->next = ereas->next;
free(ereas);
}
同样需要指针的指针,其实只要可能涉及头节点的,用指针的指针就可以了(懒人)。
int Listlength(struct List* head)//计算链表长度;
{
int count = 0;
while (head!=NULL)
{
count++;
head = head->next;
}
return count;
}
int searchNode(struct List* head, int expoly)//找到特定指数的节点位置;
{
int last = 0;
while (head->exponent != expoly)
{
head = head->next;
last++;
}
return last;
}
void printList(struct List* pList)//打印一个多项式;
{
printf("The polynomial is :");
while (pList != NULL)
{
if (pList->factor > 0)
printf("+");
printf("%dX^%d ", pList->factor, pList->exponent);
pList = pList->next;
}
}
这些都是些小程序,都是写着写着发现要一些参数然后写一个函数,烦。
void addPolynomial(struct List** summation, struct List* addend, struct List* augend)//多项式的加法;
{
while (addend != NULL && augend != NULL)
{
if (addend->exponent == augend->exponent)
{
insertNode(summation, ((addend->factor) + (augend->factor)), addend->exponent);
addend = addend->next; augend = augend->next; continue;
}
if (addend->exponent > augend->exponent)
{
insertNode(summation, addend->factor, addend->exponent);
addend = addend->next; continue;
}
if (addend->exponent < augend->exponent)
{
insertNode(summation, augend->factor, augend->exponent);
augend = augend->next; continue;
}
}
}
无与伦比的垃圾加法,其实如果要实现任意两个多项式相加的话,可以在后面加
if(A多项式==NULL)
复制B多项式后面的所有值接在后面。
同理得B
建议先把多项式排序,然后再相加,当然也可以写个函数让他两同时完成,这个加法相当于新建了一个C式,把他俩的和加里面了,(突然看到好像没有free,麻了)。
其实当时雄心壮志,是想要写N元N次多项式的加乘法的,最后就写了一个一元的,但是我个人感觉这个一元也还算完整了,当然作为链表他还缺少很多操作,但是也差不多齐活了,至于指数相同项的合并以及乘法,也就是费时间的事情而已,个人感觉从理解双指针以后,后面写的就无比顺畅了,最多就是逻辑上的问题,代码段已经问题不大了。(突然想起collate函数双指针套双指针,当时写的时候人巨慌,结果还就一点事没有)
这也就是个学习笔记类似的东西吧,没有为人师的意思。