一元稀疏多项式计算器马踏棋盘航空客运订票系统课程设计报告Word格式.docx
《一元稀疏多项式计算器马踏棋盘航空客运订票系统课程设计报告Word格式.docx》由会员分享,可在线阅读,更多相关《一元稀疏多项式计算器马踏棋盘航空客运订票系统课程设计报告Word格式.docx(53页珍藏版)》请在冰豆网上搜索。
voidCreateLink(Link&
L,intn)
{if(L!
=NULL)//首先判断是已经存在多项式,如果存在则销毁
{DestroyLink(L);
}
Linkp,newp;
L=newLNode;
L->
next=NULL;
//分配结点空间,new相当于malloc函数
(L->
data).exp=-1;
//创建头结点
p=L;
for(inti=1;
i<
=n;
i++)
{
newp=newLNode;
cout<
<
"
请输入第"
项的系数和指数:
endl;
系数:
;
cin>
>
(newp->
data).coef;
指数:
data).exp;
if(newp->
data.exp<
0)
{cout<
您输入有误,指数不允许为负值!
deletenewp;
i--;
continue;
//输入不符合要求则删除重新创建,delete相当于free函数
newp->
data.coef==0)
系数为零,重新输入!
while((p->
next!
=NULL)&
&
((p->
next->
data).exp<
data).exp))
{p=p->
next;
//p指向指数最小的那一个
if(!
JudgeIfExpSame(L,newp))
{newp->
next=p->
p->
next=newp;
}else
输入的该项指数与多项式中已存在的某项相同,请重新创建一个正确的多项式"
DestroyLink(L);
CreateLink(L,n);
//创建多项式没有成功,递归调用重新创建
break;
2.多项式相加模块的源程序
voidPolyAdd(Link&
pc,Linkpa,Linkpb)
{
Linkp1,p2,p,pd;
CopyLink(p1,pa);
CopyLink(p2,pb);
//将链表pa,pb分别复制给p1,p2
pc=newLNode;
pc->
p=pc;
//创建新链表pc来存储相加后的值
p1=p1->
p2=p2->
while(p1!
=NULL&
p2!
=NULL)
if(p1->
p2->
data.exp)//将指数小的结点的值赋给pc链表中的结点
{p->
next=p1;
p=p->
elseif(p1->
data.exp>
data.exp)
next=p2;
else//当指数相等时,将系数相加后再把指数和系数赋给pc
{p1->
data.coef=p1->
data.coef+p2->
data.coef;
data.coef!
=0)//当相加后的系数不等于0,直接赋给pc
else//当相加后的系数等于0时不存储在pc中,将p1,p2分别指向下一个结点进行相加算法
{pd=p1;
deletepd;
if(p1!
if(p2!
3.多项式相减模块的源程序
voidPolySubstract(Link&
{Linkp,pt;
CopyLink(pt,pb);
p=pt;
//将链表pb赋给链表pt
while(p!
(p->
data).coef=(-(p->
data).coef);
//将pt中的系数都乘以(-1)
PolyAdd(pc,pa,pt);
//再将pt与pa相加,就得到相减的结果
DestroyLink(pt);
4.多项式相乘模块的源程序
voidPolyMultiply(Link&
Linkp1,p2,p,pd,newp,t;
p1=pa->
p2=pb->
=NULL)//用循环的方式将p1的每个结点分别与p2中的每个结点相乘
pd=newLNode;
pd->
p=newLNode;
t=p;
while(p2)
data.coef*p2->
data.exp=p1->
data.exp+p2->
data.exp;
t->
t=t->
PolyAdd(pd,pc,p);
//将最新相乘算出来的多项式与已存在的多项式相加
CopyLink(pc,pd);
//再将相加的结果放到链表pc中去
DestroyLink(p);
DestroyLink(pd);
5.主函数源程序
voidmain()//主函数
{intn;
LinkL,La=NULL,Lb=NULL;
//La,Lb分别为创建的两个多项式
intchoose;
Menu();
//调用菜单函数
while
(1)
{cin>
choose;
switch(choose)
{case1:
请输入需要运算的第一个一元多项式的项数:
n;
if(CompareIfNum(n)==1)
输入有误,请重新输入……\n\t\t\t\t请选择:
CreateLink(La,n);
//创建链表La
请输入需要运算的第二个一元多项式的项数:
CreateLink(Lb,n);
\n\t\t\t\t请继续选择:
//创建链表Lb
case2:
if(La==NULL||Lb==NULL)
多项式不存在,请重新输入……\n\t\t\t\t请选择:
}
PolyAdd(L,La,Lb);
//将多项式相加
待相加的两个一元多项式为:
A的多项式为:
PrintList(La);
B的多项式为:
PrintList(Lb);
相加后的结果为:
PrintList(L);
case3:
PolySubstract(L,La,Lb);
//将多项式相减
相减的两个一元多项式为:
相减后的结果为:
case4:
PolyMultiply(L,La,Lb);
//将多项式相乘
相乘的两个一元多项式为:
相乘后的结果为:
case5:
一元多项式A为:
//将多项式La输出
一元多项式B为:
//将多项式Lb输出
case6:
if(La&
Lb)
{DestroyLink(La);
DestroyLink(Lb);
多项式销毁成功!
\t\t\t\t请继续选择:
else{cout<
}break;
case7:
exit(0);
//exit(0)强制终止程序,返回状态码0表示正常结束
default:
输入错误,请重新选择操作……\n\t\t\t\t请选择:
4、实验的结果及分析
*************************一元多项式的运算**********************
**
*①新建多项式*
*②加法运算*
*③减法运算*
*④相乘运算*
*⑤输出*
*⑥清空*
*⑦退出*
***************************************************************
请选择:
9
输入错误,请重新选择操作……
4
多项式不存在,请重新输入……
1
46
项数太大,请重新输入……
5
请输入第1项的系数和指数:
34
请输入第2项的系数和指数:
47
2
请输入第3项的系数和指数:
48
请输入第4项的系数和指数:
49
3
请输入第5项的系数和指数:
28
33
39
29
88
请继续选择:
48x+47x^2+49x^3+28x^4+34x^5
39x+88x^2+29x^3+33x^5
87x+135x^2+78x^3+28x^4+67x^5
9x-41x^2+20x^3+28x^4+x^5
1872x^2+6057x^3+7439x^4+6767x^5+6795x^6+5355x^7+2603x^8+924x^9+1122x^10
6
7
Pressanykeytocontinue
5、实验中出现的问题、分析及心得体会
1.时间复杂度分析
创建函数的复杂度为o(n),复制链表时为o(n),设链表a为n1个节点,链表b为n2个节点,加法运算时因为有复制过程所以如果是不理想状态复杂度为o(2(n1+n2)),减法运算时因为先将链表b复制然后又将其改成-pb,然后将-pb与pa相加,故复杂度为o(2(n1+2n2)),乘法时复杂度为o(n1*n2)
2.问题和解决方法
1.开始没有想到将链表复制,而是直接在链表上进行的操作,但是却因此改变了链表的值而影响了后面的操作使结果不如人意。
解决方法是从网上看了一个程序后,重新分配空间后将其链表复制到其上,才达到效果,不影响原来多项式的数值。
2.系数的表示方法,开始运行的时候,不是很到位,比如说当系数为1或-1时,可以省略1,还有指数1和0次方的表示比较特殊。
所以解决的时候必须分别分情况讨论。
但是又增加了程序的空间复杂度。
还有一些其他细小的问题一般都会有的,只需注意一下,也比较容易改正。
3.在课设过程中有遇到这样一个问题,就是对一个操作完成以后它不会进行下一个操作,分析之后发现switch语句中用到break,而没有循环故不进行下个选项直接跳出switch到主函数中去了,加入一个while以后就可以正常进行。
实习报告2
马踏棋盘
1.将马随机放在国际象棋的8×
8棋盘Board[8][8]的某个方格中,马按走棋规则进行移动。
要求每个方格只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×
8的方阵,输出之。
2.演示程序以用户与计算机交互方式执行,即在计算机终端上显示"
提示信息"
之后,由用户在键盘上输入演示程序中规定的运算命令;
设计思路按照顺时针顺序,每次产生一个新的位置点,并验证此位置点的可用性,需要考虑的问题包括是否超出棋盘和此点已经走过与否,如新位置点可用,并执行下一步,每次按照上一位置点生成新位置点。
如下一个位置点走不下去,进行回溯。
3.程序执行的命令包括:
(1)初始化棋盘格;
(2)选择要操作的序号;
(3)输入马的初始位置x的位置;
(4)输入马的初始位置y的位置;
(5)开始演示并输出路径;
(6)退出程序。
为实现上述程序功能,应以数组表示集合。
为此,需要两个函数,即定义棋盘和马的进步。
1.定义棋盘:
intchessboard[8][8];
操作结果:
定义一个8*8的棋盘
intDirX[]={2,1,-1,-2,-2,-1,1,2};
数组依次记录八个可走方向的横坐标
intDirY[]={1,2,2,1,-1,-2,-2,-1};
数组依次记录八个可走方向的纵坐标
2.马的进步:
voidinit()
初始条件:
棋盘已经建立
初始化,主要是将棋盘各点置零
intoutnumber(intm,intn)
求从某一点出发,可以有多少条路径可走
intmix(intm,intn)
求一方向,从该方向出发,到达的点,可以走的路径数目最小
boolisok(intm,intn);
判断某个方向是否可行
voidprint()
棋盘已经建立
将棋盘的信息打印,也即将走满的格子中的步数信息显示出来
3.本程序包含四个模块
1)主程序模块
voidmain(){
初始化:
do{
选择命令并处理命令;
退出命令。
}while(choice!
=3)
2)实现原始棋盘模板
3)实现棋盘的定义模板;
4)实现马走日的进步模板。
各模块之间的调用关系如下:
主程序模块
原始棋盘模板
棋盘的定义模板
输出路径
进步模板
路点可行
1.棋盘的定义
//数组依次记录八个可走方向的横坐标
intDirY[]={1,2,2,1,-1,-2,-2,-1};
//数组依次记录八个可走方向的纵坐标
intchessboard[8][8];
//定义了一个8*8的棋盘
2.马的进步函数
voidinit();
//初始化,主要是将棋盘各点置零
intoutnumber(intm,intn);
//求从某一点出发,可以有多少条路径可走
intmix(intm,intn);
//求一方向,从该方向出发,到达的点,可以走的路径数目最小
voidprint();
//打印棋盘结果
boolisok(intm,intn);
//判断某个方向是否可行
3.主函数和其他函数算法
voidmain()
cout<
******************************马踏棋盘
intchoice=0;
do{
if(choice==1)
{//原始棋盘的情况
if(choice==2)
{
init();
//用户的输入过程
请输入坐标
输入的坐标正确与否
}
chessboard[x][y]=step;
//记录初始位置,将该点的坐标定义为步数step
for(step=2;
step<
65;
step++)
{//应用贪心算法来求解,没有回溯过程
i=mix(x,y);
//求从某点出发可走的方向中,出口数最小的方向
x+=DirX[i];
//前进一步
y+=DirY[i];
chessboard[x][y]=step;
}
print();
//走完64步,利用贪心算法一定会有解,故无回溯,直接打印结果
}
if(choice!
=1&
choice!
=2&
=3)//选择不在指定的三个数中,需重新输入,
cout<
重新输入你的选择!
}while(choice!
=3);
//退出这个程序
}
voidinit()//初始化棋盘,将所有的格子初始化为零
for(inti=0;
8;
i++)
for(intj=0;
j<
j++)
chessboard[i][j]=0;
intmix(intm,intn)//传入参数为某点的坐标,函数返回从该点出发的所有可行的方向中,出口数最小的方向
{//出口数为某点可走的方向数
intmixdir=0,mixnumber=9,a=0;
//mixdir记录最小出口数的方向,mixnumber记录该方向的出口数,也即所有方向中最小的出口数
{
if(isok((m+DirX[i]),(n+DirY[i])))
{//首先判断某个方向是否可行
a=outnumber((m+DirX[i]),(n+DirY[i]));
//计算该方向的出口
if(a&
(a<
mixnumber))
{//如果该方向可行并且该方向的出口数比已知的最小的出口数小
mixnumber=a;
//将mixnumber改为该出口数
mixdir=i;
//将该方向记录为最小出口数方向