长整数运算说明书.docx
- 文档编号:27935337
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:51
- 大小:173.60KB
长整数运算说明书.docx
《长整数运算说明书.docx》由会员分享,可在线阅读,更多相关《长整数运算说明书.docx(51页珍藏版)》请在冰豆网上搜索。
长整数运算说明书
摘要
该设计要求学生设计程序,实现两个任意长的整数求和及差的运算问题。
通过该题目的设计过程,可以加深理解线性表的逻辑结构、存储结构,掌握线性表上基本运算的实现,进一步理解和熟练掌握课本中所学的各种数据结构,学会如何把学到的知识用于解决实际问题,培养学生的动手能力。
关键词:
数据结构;长整数;运算问题;C语言
前言
在计算机及相关专业众多的基础课程里面,算法与数据结构是基础而又十分重要的课程。
本学期开设的《算法与数据结构》课程,在学习科目的第一节课起,张老师就为我们阐述了它的重要性。
它对我们来说具有一定的难度。
它是其它编程语言的一门基本学科。
尽管不好学,但是我们必须学好这门课程,这对于我们计算机专业的学生来说意义重大。
经过一个学期的理论知识的学习,对于数据结构相关的知识有了一定的了解。
这是一门纯属于设计的科目,它需用把理论变为上机调试和具体实践。
在课程结束之后。
老师为我们安排了这次为期两周的课程设计。
目的就是让我们自己在计算机上自己设计算法来实现相应的功能以及锻炼学生的动手能力和实践能力,最重要的是要把我们所学的数据结构的理论知识应运到实践中去。
这次课程设计的题目是“长整数运算”,要求学生自己查阅相关资料,完成相应的任务,自己上机设计算法,调试程序,运行出结果,以此来加深理解线性表、查找表的逻辑结构、存储结构,掌握查找、排序等基本运算的实现,进一步理解和熟练掌握课本中所学的各种数据结构,学会如何把学到的知识用于解决实际问题,培养自己的动手能力。
正文
1.采用类c语言定义相关的数据类型
#include
#include
typedefstructdnode{
intdata;//头节点的data域保存数的正负。
1正,0负。
structdnode*prior,*next;
}dnode;
dnode*r1,*r2,*head1,*head2,*head3;
dnode*head_temp;
dnode*creat(){//表尾插入法产生一个带头节点的双向循环链表,结果:
表头是高位,表尾是低位,返回头指针
dnode*head,*p,*s;
intx,flag=1;//flag--是否继续输入的标志
head=(dnode*)malloc(sizeof(dnode));
p=head;
while(flag){
scanf("%c");
scanf("%d",&x);
if(x>=0&&x<10000){//输入数的合法性判断
s=(dnode*)malloc(sizeof(dnode));
s->data=x;
p->next=s;
s->prior=p;
p=s;
}
if(x>=10000){//输入过大,判错
printf("inputoverflow");
flag=0;
returnNULL;
}
if(x<0)flag=0;//输入负数就转到下一步
}//while(flag)
//在链表的首尾建立联系
head->prior=p;
p->next=head;
returnhead;
}//creat().................checked!
dnode*core_add(dnode*h1,dnode*h2){//部分加法--两个正数相加。
传入两个头指针。
返回结果:
表头是高位,表尾是低位,返回头指针
intsum=0,inc=0;//inc=1进位,inc=0不进位
dnode*p1,*p2,*p,*s,*h3;
h3=(dnode*)malloc(sizeof(dnode));
p=h3;//动指针p
for(p1=h1->prior,p2=h2->prior;(p1!
=h1)&&(p2!
=h2);p1=p1->prior,p2=p2->prior){
//从表尾开始,至某个指针(p1,p2)回到头节点为止
sum=p1->data+p2->data+inc;
if(sum>=10000){//进位
inc=1;
sum-=10000;
}
else{inc=0;}
s=(dnode*)malloc(sizeof(dnode));
s->data=sum;
s->next=p;
p->prior=s;
p=s;//表头是高位,表尾是低位,建立结果链表
}//for
if(p1==h1&&p2==h2){//两数节数相同
if(!
inc){//不进位
s->prior=h3;
h3->next=s;
returnh3;
}//if(不进位)
else{//进位
s=(dnode*)malloc(sizeof(dnode));
s->data=1;
s->next=p;
p->prior=s;
s->prior=h3;
h3->next=s;
returnh3;
}//else
}//if(两数节数相同)
if((p1==h1)&&(p2!
=h2)){//h1加完,h2有剩余段
while(p2!
=h2){
if((sum=p2->data+inc)>10000){//进位,只进一次
inc=1;
sum-=10000;
}
else{inc=0;}
s=(dnode*)malloc(sizeof(dnode));
s->data=sum;
s->next=p;
p->prior=s;
p=s;
p2=p2->prior;
}//while(p2!
=h2)
s->prior=h3;
h3->next=s;
returnh3;
}//if(h1加完,h2有剩余段)
if((p2==h2)&&(p1!
=h1)){//h2加完,h1有剩余段
while(p1!
=h1){
if((sum=p1->data+inc)>=10000){//进位,只进一次
inc=1;
sum-=10000;
}
else{inc=0;}
s=(dnode*)malloc(sizeof(dnode));
s->data=sum;
s->next=p;
p->prior=s;
p=s;
p1=p1->prior;
}//while(p1!
=h1)
s->prior=h3;
h3->next=s;
returnh3;
}//if(h2加完,h1有剩余段)
returnNULL;//仍未出口就判错
}//core_add().............checked
dnode*core_sub(dnode*h1,dnode*h2){//部分减法--大数减小数。
传入两个头指针。
返回结果:
表头是高位,表尾是低位,返回头指针
dnode*p1,*p2,*p,*s,*h3;
intdec=0,resl=0;//dec借位标志,resl暂存相减的结果
h3=(dnode*)malloc(sizeof(dnode));
p=h3;//动指针p
for(p1=h1->prior,p2=h2->prior;p2!
=h2;p1=p1->prior,p2=p2->prior){
//从h1,h2尾节点开始,至指针p2回到头节点为止
resl=(p1->data)-(p2->data)-dec;
if(resl<0){//借位
dec=1;
resl+=10000;
}//if(借位)
else{dec=0;}
s=(dnode*)malloc(sizeof(dnode));
s->data=resl;
s->next=p;
p->prior=s;
p=s;
}//for()
if((p2==h2)&&(p1==h2))//两数的段数一样
{
s->prior=h3;
h3->next=s;
returnh3;
}//if(两数的段数一样)
else{//被减数h1有剩余段
while(p1!
=h1){
resl=p1->data-dec;
if(resl<0){//借位
dec=1;
resl+=10000;
}//if(借位)
else{dec=0;}//完成借位后,dec置零
s=(dnode*)malloc(sizeof(dnode));
s->data=resl;
s->next=p;
p->prior=s;
p=s;
p1=p1->prior;
}//while(p1!
=h1)
s->prior=h3;
h3->next=s;
returnh3;
}//else(被减数h1有剩余段)
returnNULL;//仍未出口就判错
}//core_sub().................checked
intcmp(dnode*h1,dnode*h2){//比较绝对值的函数。
|h1|>|h2|,返回1;|h1|<|h2|,返回-1;|h1|=|h2|,返回0
intc1=0,c2=0;//段数计数器
dnode*p1,*p2;
for(p1=h1;p1!
=h1;p1=p1->next)c1++;
for(p2=h2;p2!
=h2;p2=p2->next)c2++;
//先比较段数
if(c1>c2)
return1;
if(c2>c1)
return-1;
else{
//段数相同的情况下,从高位(头)到低位(尾)逐段比较大小
for(p1=h1->next,p2=p2->next;p1!
=h1;p1=p1->next,p2=p2->next){
if(p1->data==p2->data)continue;
if((p1->data)>(p2->data))return1;
elsereturn-1;
}
return0;//比到最后不分大小,就是一样大
}//else
}//cmp()..............checked
voidprint(intdata){//补零打印一个数。
只被display()调用。
if(data>=1000)
printf("%d",data);
else
if(data>=100)
printf("0%d",data);
else
if(data>=10)
printf("00%d,",data);
else
printf("000%d",data);
}//print()
voiddisplay(dnode*h){//显示一个长整数的数值部分,传入的参数是头指针
dnode*p;
p=h->next;//p指头
while(p!
=h->prior){//从高位到地位输出长整数
print(p->data);
printf(",");
p=p->next;
}
printf("%04d",p->data);
printf("\n");
}//display()...........checked
voidadd(dnode*h1,dnode*h2){//加法,a+b=c
dnode*h3;
intflag=0;
if((h1->data)&&(h2->data)){//a+,b+
h3=core_add(h1,h2);
h3->data=1;
printf("+");
display(h3);
}
if(!
(h1->data)&&!
(h2->data)){//a-,b-
h3=core_add(h1,h2);
h3->data=0;
printf("-");
display(h3);
}
if((h1->data)&&!
(h2->data)){//a+,b-
switch(flag=cmp(h1,h2)){
case1:
//|a|>|b|
{
h3=core_sub(h1,h2);
h3->data=1;
printf("+");
display(h3);
break;
}
case0:
break;
case-1:
//|a|<|b|
{
h3=core_sub(h2,h1);
h3->data=0;
printf("-");
display(h3);
break;
}
}//switch(flag)
}//if(a+,b-)
if((!
h1->data)&&(h2->data)){//a-,b+
switch(flag=cmp(h1,h2)){
case1:
//|a|>|b|
{
h3=core_sub(h1,h2);
h3->data=0;
printf("-");
display(h3);
break;
}
case0:
break;
case-1:
//|a|<|b|
{
h3=core_sub(h2,h1);
h3->data=1;
printf("+");
display(h3);
break;
}
}//switch(flag)
}//if(a-,b+)
}//add().................checked
voidsub(dnode*h1,dnode*h2){//减法,a-b=c
dnode*h3;
intflag=0;
if((h1->data)&&!
(h2->data)){//a+,b-
h3=core_add(h1,h2);
h3->data=1;
printf("+");
display(h3);
}//if(a+,b-)
if(!
(h1->data)&&(h2->data)){//a-,b+
h3=core_add(h1,h2);
h3->data=0;
printf("-");
display(h3);
}//if(a-,b+)
if((h1->data)&&(h2->data)){//a+,b+
switch(flag=cmp(h1,h2)){
case1:
//|a|>|b|
{
h3=core_sub(h1,h2);
h3->data=1;
printf("+");
display(h3);
break;
}
case0:
break;
case-1:
//|a|<|b|
{
h3=core_sub(h2,h1);
h3->data=0;
printf("-");
display(h3);
break;
}
}//switch(flag)
}//if(a+,b+)
if(!
(h1->data)&&!
(h2->data)){//a-,b-
switch(flag=cmp(h1,h2)){
case1:
//|a|>|b|
{
h3=core_sub(h1,h2);
h3->data=0;
printf("-");
display(h3);
break;
}
case0:
break;
case-1:
//|a|<|b|
{
h3=core_sub(h2,h1);
h3->data=1;
printf("+");
display(h3);
break;
}
}//switch(flag)
}//if(a-,b-)
}//sub().........checked!
intchar_to_int(chara){//存储符号位
switch(a){
case'+':
return1;break;
case'-':
return0;break;
}
return-1;
}//char_to_int()..............checked!
voidinput_and_init(){//初始化2个数据的大小
chara;
intflag1,flag2;
printf("输入第一个数字的正负符号(+,-)\n");//输入符号
scanf("%c",&a);
scanf("%c",&a);
flag1=char_to_int(a);
printf("输入第一个数字每次输入4位用逗号隔开输入负数结束输入\n");
head1=creat();//产生第一个数,得到它的头指针
head1->data=flag1;
printf("输入第二个数字的正负符号(+,-)\n");
scanf("%c",&a);
scanf("%c",&a);
flag2=char_to_int(a);
printf("输入第二个数字每次输入4位用逗号隔开输入负数结束输入\n");
head2=creat();//产生第2个数,得到它的头指针
head2->data=flag2;
}//input_and_init()..............checked!
voidmain_messsage(){//菜单信息
printf("***********************\n");
printf("*算法与数据结构课程设计-----长整数的运算*\n");
printf("**\n");
printf("*1:
输入*\n");
printf("*2:
加法*\n");
printf("*3:
减法*\n");
printf("*4:
退出*\n");
printf("***********************\n");
printf("\n");
printf("\n");
}
voidmain(){
intflag;
main_messsage();//菜单信息
scanf("%d",&flag);//输入选择
while(flag!
=4){//输入4退出
switch(flag){
case1:
input_and_init();break;//输入1:
初始2个数据
case2:
add(head1,head2);break;//输入2:
求和
case3:
sub(head1,head2);break;//输入3:
求差
}//switch()
main_messsage();
scanf("%d",&flag);
}//while
}//main
3函数的调用关系图
4.调试分析
a、调试中遇到的问题及对问题的解决方法
本程序在一开始,基本上没有太大的问题,大部分功能都能完整的实现,但是本程序结构严谨,要明确函数的嵌套关系以及执行过程。
此程序执行时不可忽略操作者选择整数的正负,先说明正负,在进行数据的输入,然后选择菜单栏里执行的运算。
b、算法的时间复杂度和空间复杂度
设该算法的结点记录为n,则通过计算可得该算法的时间复杂度为O(n2),该算法的空间复杂度为8.76KB。
5.测试结果
1选择菜单界面如下所示:
2选择1进入输入:
3输入第一个数字正负号(比如+号):
4输入第一个数字每次输入4位用逗号隔开,输入负数结束(如以-1结束):
5输入第二个数字正负号:
6输入第二个数字每次输入4位用逗号隔开,输入负数结尾:
7选择运算:
同样步骤可以进行其他运算,如下列两长整数想减:
6.源程序(带注释)
#include
#include
typedefstructdnode{
intdata;//头节点的data域保存数的正负。
1正,0负。
structdnode*prior,*next;
}dnode;
dnode*r1,*r2,*head1,*head2,*head3;
dnode*head_temp;
dnode*creat(){//表尾插入法产生一个带头节点的双向循环链表,结果:
表头是高位,表尾是低位,返回头指针
dnode*head,*p,*s;
intx,flag=1;//flag--是否继续输入的标志
head=(dnode*)malloc(sizeof(dnode));
p=head;
while(flag){
scanf("%c");
scanf("%d",&x);
if(x>=0&&x<10000){//输入数的合法性判断
s=(dnode*)malloc(sizeof(dnode));
s->data=x;
p->next=s;
s->prior=p;
p=s;
}
if(x>=10000){//输入过大,判错
printf("inputoverflow");
flag=0;
returnNULL;
}
if(x<0)flag=0;//输入负数就转到下一步
}//while(flag)
//在链表的首尾建立联系
head->prior=p;
p->next=head;
returnhead;
}//creat().................checked!
dnode*core_add(dnode*h1,dnode*h2){//部分加法--两个正数相加。
传入两个头指针。
返回结果:
表头是高位,表尾是低位,返回头指针
intsum=0,inc=0;//inc=1进位,inc=0不进位
dnode*p1,*p2,*p,*s,*h3;
h3=(dnode*)malloc(sizeof(dnode));
p=h3;//动指针p
for(p1=h1->prior,p2=h2->prior;(p1!
=h1)&&(p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 整数 运算 说明书