逻辑结构设计
根据多项式中每个项指数的大小,按顺序排列而得到的线性结构。(其中数据元素存在“一对一关系”,这种一对一的关系在数据结构中通常由数据元素的“前驱”和“后继”方式进行描述和实现,直观上呈现出“线状”特征,也称线性表。)
存储结构设计
- 题目多项式存在多个独立且相互关联组成一个多项式的项,结合逻辑结构,可知用链式存储(分散式存储)最为合适。(使用任意可用的地址空间来存放数据元素本身,数据之间逻辑关系通过附加指针显示实现。这里,地址空间“任意”的含义是指计算机随机分配空闲地址,存储的区域可以是不连续的和零星分布的。此时,存储空间可以根据需要实时申请,当不需要时,也可以释放。在链式存储技术中,数据结点通常分为两个部分,一个是指针域,用来存放数据之间关联的信息;另一个是数据域,用来存放数据本身的值信息。链式存储方式灵活,应用广泛。链式存储是一种基于数据关系的分散式存储)。
- 程序使用了带有首尾指针的双向链表来按照各个项指数由小到大顺序存储多项式;链表中非首结点的数据域存放项的系数(double类型)和指数(int类型)、指针域存放前后指针指向该向的前驱和后继结点;首结点数据域存放链表中结点(多项式的项)的个数(int类型)。指针域存放指针指向后继结点(含多项式第一个项的结点)。
主要操作设计
- PloyNode类,设计两个数据域,有double类型的系数coef,和int类型的指数expn。分别写他们的geter,seter方法。方便后面直接操作PloyNode存储单项的指数和系数。
- 写PloynList类继承自MySingleLink类,MySingleLink类中写了单链表的一些基本方法。而PloynList类主要写了insert(PloynNode)方法,方便后期插入多项式单项节点,并写了show()方法,方便把运算好的多项式展示出到控制台上。
- TestPolynList类写了众多静态方法。
(1) cmp(PloyNode a,PloyNode b)方法用来判断两个节点的指数的大小,方便后面计算时用。
(2) createPolynList()方法用来创建多项式链表,将用户输入的字符用正则表达式进行拆分成系数、运算符、指数;并在里面按指数升序将每一项的系数和指数存入链表节点中。并返回此链表。
(3) addPolyn(PolynList LA,PolynList LB)方法是两个多项式相加的方法。通过指针两个多项式链表的头节点往后搜查,由于按照升序,所以找到一样的指数的,就把他们的系数相加。并返回加好之后的链表。
(4) substract(PolynList LA, PolynList LB) 方法是相减的方法,与加法类似,原理几乎一样。并返回减好之后的链表。
(5) evaluation(PolynList le, double num)是求值的方法,就是将每个值代入通过for循环将最终结果计算出来。
(6) derication(PolynList le)求导方法,根据数学求导法则写代码即可。
(7) sortList(PolynList list)对链表中的节点按指数升序排列的方法,主要用了冒泡排序。
技术难点与解决方法
- 每次输入数据若有重复的指数需要处理
解决方法:
在创建链表时需要对数据进行重复指数合并处理。创建一个ArrayList保存存过的指数,每次存数据时,需要遍历集合查重,若有重复则需要做合并处理。若不重复,则把此指数放入集合中。
- 多项式的输出,对特殊的处理,比如多项式系数等于1.0可省略,指数等于0可直接输出系数等等,虽不难,但情况众多,需要用if-else逐个列举。
// display()方法
public void show() throws Exception {
System.out.printf("一共有%d项\n",length());
System.out.print("结果为:");
for (int i = 0; i < length(); i++) {
int expn = ((PloyNode)this.get(i)).expn;
double coef = ((PloyNode)this.get(i)).coef;
if(i != 0){//非第一项
if (coef > 0){
if (coef == 1.0){
if (expn == 0){
System.out.print("+1");
}else if(expn == 1){
System.out.print("+" + "X");
}else{
System.out.print("+" + "X^" + expn );
}
}else{
if (expn == 0){
System.out.print("+" + coef );
}else if(expn == 1){
System.out.print("+" + coef + "X" );
}
else {
System.out.print("+" + coef + "X^" + expn );
}
}
}
if(coef < 0){
if (coef == -1.0) {
if (expn == 0){
System.out.print("-1");
}else if(expn == 1){
System.out.print("-" + "X");
}
else{
System.out.print("-" + "X^" + expn);
}
}else{
if (expn == 0){
System.out.print(coef);
}else if(expn == 1){
System.out.print(coef + "X");
}
else{
System.out.print(coef + "X^" + expn );
}
}
}
}else{//第一项
if (coef == 1.0){
if (expn == 0){
System.out.print("1");
}else if(expn == 1){
System.out.print("X");
}
else{
System.out.print("X^" + expn);
}
}
else if (coef == -1.0){
if (expn == 0){
System.out.print("-1");
}else if(expn == 1){
System.out.println("-X");
}
else{
System.out.print("-X^" + expn );
}
}
else{
if (expn == 0){
System.out.print(coef);
}else{
System.out.print(coef + "X^" + expn);
}
}
}
}
System.out.println();
}
- 实现多项式加减法的算法
解决思路:由于输入的多项式已经经过排序和同指数幂项合并,所以只需要两个指针分别从两个多项式头节点往后遍历,若不同,先把较小幂的放入新多项式链表,若相同则做加减运算,之后依次遍历,直到一个已经遍历完,可以把另一个全部加入新链表。并返回此链表。
/**
* 多项式加法
* **/
public static PolynList addPolyn(PolynList LA,PolynList LB){
Node ha = LA.getHead();//ha指向新链表的尾戒点
Node qa = LA.getHead().getNext();
Node qb = LB.getHead().getNext();
System.out.println(qb.getData());
while(qa != null && qb != null){
PloyNode a = (PloyNode)qa.getData();
PloyNode b = (PloyNode)qb.getData();
switch (cmp(a,b)){
case -1:
ha.setNext(qa);
ha = qa;
qa = qa.getNext();
break;
case 0:
double sum = a.coef + b.coef;
if (sum != 0.0){
a.coef = sum;
ha.setNext(qa);
ha=qa;
qa = qa.getNext();
qb = qb.getNext();
}else{
PloyNode node = new PloyNode(0,0);
ha.setNext(new Node(node));
qa = qa.getNext();
qb = qb.getNext();
}
break;
case 1:
if (((PloyNode) qb.getData()).coef==0.0 && ((PloyNode) qb.getData()).expn==0){
qb = qb.getNext();
break;
}
ha.setNext(qb);
ha = qb;
qb = qb.getNext();
break;
}
}
while(qa != null){
ha.setNext(qa);
ha=qa;
qa = qa.getNext();
}
while (qb != null){
ha.setNext(qb);
qb = qb.getNext();
}
// if (ha.getNext() == null){
// PloyNode node = new PloyNode(0,0);
ha.setNext(new Node(node));
// }
return LA;
}