长整数四则运算源代码_数据结构(1)

f7f
// 长整数四则运算.cpp : 定义控制台应用程序的入口点。
//

#include
#include
#include
#include
#include
#include
#define LEN sizeof(struct Node)
#define MAX 1000
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef struct Node
{
int data;
struct Node *prior,*next;
}Node,*NodeList;

//=======================================输入模块=========================================
//求指数函数值
int axp(int a,int k)
{
int r=1;
if(k==0)
return 1;
for(;k>0;k--)
r=r*a;
return r;
}

//输入转换函数
Status conversion(char str[],NodeList &oprh)
{//将字符串形式的操作数转换成所需的类型
NodeList p;
int i,k,buffer;
k=buffer=0;
oprh=(NodeList)malloc(LEN);
oprh->next=oprh;
oprh->prior=oprh;
for(i=strlen(str)-1;i>=0;i--)
{
//若输入的数不合法就返回重新输入
if((i!=0 || (str[0]!='-' && str[0]!='+'))&&(str[i]>'9' || str[i]<'0'))
return ERROR;
if(str[0]=='0' && str[1]!='\0')
return ERROR;
if((str[0]=='-' || str[0]=='+') && str[1]=='0')
return ERROR;
if(str[i]!='-' && str[i]!='+')
{
buffer=buffer+(str[i]-'0')*axp(10,k);
k++;
if(k==4 || str[i-1]=='-' || str[i-1]=='+' || i==0)
{//将新建结点插入到头结点之后
p=(NodeList)malloc(LEN);
oprh->next->prior=p;
p->prior=oprh;
p->next=oprh->next;
oprh->next=p;
p->data=buffer;
buffer=k=0;
}
}
}
if(str[0]=='-')
oprh->data='-';
else
oprh->data='+';
return OK;
}

//输入函数
Status input(NodeList &opr1,NodeList &opr2,char str[])
{
int flag=OK;
printf("\n请输入第一个操作数:\n");
scanf("%s",str);
getchar();
flag=conversion(str,opr1);
while(!flag)
{
printf("ERROR!Input again:\n");
scanf("%s",str);
getchar();
flag=conversion(str,opr1);
}

printf("\n请输入第二个操作数:\n");
scanf("%s",str);
getchar();
flag=conversion(str,opr2);
while(!flag)
{
printf("ERROR!Input again:\n");
scanf("%s",str);
getchar();
flag=conversion(str,opr2);
}
return OK;
}
//========================================================================================


//=======================================输出模块=========================================
//输出函数
Status output(NodeList oprr,char str[])
{
Status initbuf(char str[]);
NodeList p;
int i,j,num[4];
if(!oprr)
return ERROR;
p=oprr;
i=j=0;
initbuf(str);
if(oprr->data=='-')
str[i++]='-';
p=p->next;
if(p->next==oprr && p->data==0)//若要输出的数为0则执行
str[i++]='0';
else
while(p!=oprr)
{
num[0]=p->data/1000;
num[1]=(p->data-num[0]*1000)/100;
num[2]=(p->data-num[0]*1000-num[1]*100)/10;
nu

m[3]=p->data-num[0]*1000-num[1]*100-num[2]*10;
while(j<4)
{
if(num[j]!=0 || (str[0]=='-' && str[1]!='\0')||(str[0]!='-' && str[0]!='\0'))
//此判断语句是为了避免输出诸如:00123…的情况
str[i++]=num[j]+'0';
j++;
}
p=p->next;
j=0;
}
str[i]='\0';
printf("%s",str);
printf("\n");
return OK;
}
//========================================================================================


//==================================预处理及杂项操作模块==================================

//缓冲区部分初始化函数
Status initbuf(char str[])
{
int i;
for(i=0;i<=10;i++)
str[i]='\0';
return OK;
}

//比较链表长度函数
int cmplinklen(NodeList opr1,NodeList opr2)
{//opr1链比opr2链长则返回1,短则返回-1,否则返回0
NodeList p1,p2;
p1=opr1->prior;
p2=opr2->prior;
while(p1->prior!=opr1 && p2->prior!=opr2)
{
p1=p1->prior;
p2=p2->prior;
}
if(p1->prior!=opr1)
return 1;
if(p2->prior!=opr2)
return -1;
return 0;
}

//求链表长度
int length(NodeList oprr)
{
int count=0;
NodeList p
103f
=oprr->next;
while(p!=oprr)
{
count++;
p=p->next;
}
return count;
}

//生成指定长度链表
Status Creat(NodeList &oprr,int len)
{
NodeList p;
oprr=(NodeList)malloc(LEN);
p=oprr;
while(len>0)
{
p->next=(NodeList)malloc(LEN);
p->next->data='?';
p->next->prior=p;
p=p->next;
len--;
}
p->next=oprr;
oprr->prior=p;
return OK;
}
//比较opr1、opr2绝对值的大小
int compare(NodeList opr1,NodeList opr2)
{
NodeList p1,p2;
p1=opr1->next;
p2=opr2->next;
if(cmplinklen(opr1,opr2)==1)//opr1比较长
return 1;
else if(cmplinklen(opr1,opr2)==-1)//opr2比较长
return -1;
else//长度相等的情况
{
while(p1->data==p2->data && p1->next!=opr1)//注意不要少了p1->next!=opr1这个条件
{
p1=p1->next;
p2=p2->next;
}
if(p1->data>p2->data)
return 1;
else if(p1->datadata)
return -1;
else
return 0;
}
}

//-----------------------初始化链表函数-----------------------
Status init(NodeList &oppr)
{
oppr=NULL;
return OK;
}//init

//销毁链表函数
Status distroy(NodeList &oprr)
{
NodeList q;
if(oprr)
{
q=oprr->next;
while(q!=oprr)
{
free(q->prior);
q=q->next;
}
}
oprr=NULL;
return OK;
}//distroy

//链表短赋值函数
Status evaluate(NodeList &opri,int i)
{//将i的值转换成万进制类型,i为整形变量
opri=(NodeList)malloc(LEN);
opri->data='+';
opri->next=(NodeList)malloc(LEN);
opri->next->data=i;
opri->next->next=opri;
opri->prior=opri->next;
opri->next->prior=opri;
return OK;
}//evaluate

//========================================================================================


//=======================================

加减法模块=======================================

//加法基本操作
Status add_bas(NodeList opr1,NodeList opr2,NodeList &oprr)
{//本算法实现A,B相加的操作。
int CF,buffer;
NodeList p1,p2,p3;
oprr=(NodeList)malloc(LEN);
oprr->next=oprr;
oprr->prior=oprr;
p1=opr1->prior;
p2=opr2->prior;
CF=buffer=0;
while(p1!=opr1 && p2!=opr2)
{
buffer=p1->data+p2->data+CF;
CF=buffer/10000;//若buffer的值大于9999则产生进位,赋给CF
//将新建结点插入到头结点之后
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer%10000;//应该将buffer的第四位赋给p3->data
//..........................
p1=p1->prior;
p2=p2->prior;
}
while(p1!=opr1)
{//处理opr1链的剩余部分
buffer=p1->data+CF;
CF=buffer/10000;
//将新建结点插入到头结点之后
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer%10000;
//..........................
p1=p1->prior;
}
while(p2!=opr2)
{//处理opr2链的剩余部分
buffer=p2->data+CF;
CF=buffer/10000;
//将新建结点插入到头结点之后
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer%10000;
//..........................
p2=p2->prior;
}
if(CF)
{
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=CF;
}
oprr->data='+';
return OK;
}

//减法基本操作
Status sub_bas(NodeList opr1,NodeList opr2,NodeList &oprr)
{//本算法实现A,B相减的操作。
//将A链分成与B链长相等的底位部分,和剩余的高位部分,并做相应处理。
int CF,buffer,flag;
NodeList p1,p2,p3,qh,qt,qq;
oprr=(NodeList)malloc(LEN);
oprr->next=oprr;
oprr->prior=oprr;
p1=opr1->prior;
p2=opr2->prior;
CF=buffer=flag=0;
while(p2!=opr2)
{//opr2链的长度小于等于opr1链的
if(p1->data<(p2->data+CF))
{
buffer=10000+p1->data-(p2->data+CF);
CF=1;
}
else
{
buffer=p1->data-(p2->data+CF);
CF=0;
}
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer;

p1=p1->prior;
p2=p2->prior;
}
while(p1!=opr1)
{//处理opr1链剩下的部分
if(p1->data{
buffer=10000+p1->
103f
data-CF;
CF=1;
}
else
{
buffer=p1->data-CF;
CF=0;
}
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer;

p1=p1->prior;
}
//处理链表开头结点值为0的无意义情况,若链表本身表示0,则不做如下处理
p3=oprr->next;
while(p3->data==0 && p3->next!=oprr)
{
p3=p3->

next;
flag=1;
}
if(flag)
{
qh=oprr->next;//保存无用结点的头尾指针
qt=p3->prior;//为释放做准备
oprr->next=p3;//重接next链
p3->prior=oprr;//重接prior链
qt->next=NULL;
while(qh!=NULL)
{//释放无用结点
qq=qh;
qh=qh->next;
free(qq);
}
}
//--------------------------------------------------------
oprr->data='+';
return OK;
}

//---------------------带符号加法函数---------------------
Status add(NodeList opr1,NodeList opr2,NodeList &oprr)
{
if(opr1==NULL || opr2==NULL)
return ERROR;
if(opr1->data==opr2->data)
{//opr1,opr2符号相同
add_bas(opr1,opr2,oprr);
if(opr1->data=='+')//opr1与opr2均为正数,即A+B的形式(A,B均是正数,下同)
oprr->data='+';
else//opr1与opr2均为负数,即(-A)+(-B)的形式
oprr->data='-';
}//if(opr1->data==opr2->data)
else
{//符号不相同
if(opr1->data=='+')
{//A+(-B)的情况
if(compare(opr1,opr2)==-1)
{//Asub_bas(opr2,opr1,oprr);
oprr->data='-';
}//if(compare(opr1,opr2)==-1)
else
{//A>=B的情况
sub_bas(opr1,opr2,oprr);
oprr->data='+';
}//else
}//if(opr1->data='+' && opr2->data='-')
else
{//(-A)+B的情况
if(compare(opr1,opr2)==1)
{//A>B的情况
sub_bas(opr1,opr2,oprr);
oprr->data='-';
}//if(compare(opr1,opr2)==1)
else
{//A<=B的情况
sub_bas(opr2,opr1,oprr);
oprr->data='+';
}//else
}//else
}//else
return OK;
}//add

//---------------------带符号减法函数----------------------
Status sub(NodeList opr1,NodeList opr2,NodeList &oprr)
{
if(opr1==NULL || opr2==NULL)
return ERROR;
if(opr1->data==opr2->data)
{//opr1,opr2符号相同
if(opr1->data=='+')
{//A-B的情况
if(compare(opr1,opr2)==-1)
{//Asub_bas(opr2,opr1,oprr);
oprr->data='-';
}//if(compare(opr1,opr2)==-1)
else
{//A>=B的情况
sub_bas(opr1,opr2,oprr);
oprr->data='+';
}//else
}//if(opr1->data='+')
else
{//(-A)-(-B)的情况
if(compare(opr1,opr2)==1)
{//A>B的情况
sub_bas(opr1,opr2,oprr);
oprr->data='-';
}//if(compare(opr1,opr2)==1)
else
{//A<=B的情况
sub_bas(opr2,opr1,oprr);
oprr->data='+';
}//else
}//else
}//if(opr1->data!=opr2->data)
else
{//opr1,opr2符号不同
add_bas(opr1,opr2,oprr);
if(opr1->data=='+')//A-(-B)
oprr->data='+';
else//(-A)-B
oprr->data='-';
}//else
return OK;
}//sub
//========================================================================================


//=========================================乘法模块=======================================
//乘法函数
Status imul(NodeList opr1,NodeList opr2,NodeList &oprr)
{
NodeList ph1,ph2,pt1,pt2,p3,pt3,qh,qt,qq;
int len,CF,flag;
long buffer;
if(compare(opr1,opr2)==-1)
{//若opr1比opr2小则被乘数跟乘数调换
ph1=opr2;


pt1=ph1->prior;
ph2=opr1;
pt2=ph2->prior;
}
else
{
ph1=opr1;
pt1=ph1->prior;
ph2=opr2;
pt2=ph2->prior;
}
len=length(opr1)+length(opr2);
Creat(oprr,len);
qq=oprr->next;
while(qq!=oprr)
{
qq->data=0;
qq=qq->next;
}
buffer=CF=0;
p3=oprr->prior;
while(pt2!=ph2)
{
pt1=ph1->prior;
pt3=p3;
while(pt1!=ph1)
{
buffer=pt1->data*pt2->data+pt3->data+CF;
CF=(int)buffer/10000;
pt3->data=(int)buffer%10000;
pt1=pt1->prior;
pt3=pt3->prior;
}
pt3->data=CF;
CF=0;
pt2=pt2->prior;
p3=p3->prior;
}
//处理链表开头结点值为0的无意义情况,若链表本身表示0,则不做如下处理
flag=0;
p3=oprr->next;
while(p3->data==0 && p3->next!=oprr)
{
p3=p3->next;
flag=1;
}
if(flag)
{
qh=oprr->next;//保存无用结点的头尾指针
qt=p3->prior;//为释放做准备
oprr->next=p3;//重接next链
p3->prior=oprr;//重接pr
103f
ior链
qt->next=NULL;
while(qh!=NULL)
{//释放无用结点
qq=qh;
qh=qh->next;
free(qq);
}
}
//..................................................................
/*不用以下代码是因为其不适合类似100000000000×0的情况
p3=oprr->next;
if(p3->data==0 && p3->next!=oprr)
{
qq=p3;
p3=p3->next;
oprr->next=p3;
p3->prior=oprr;
free(qq);
}*/
if(opr1->data==opr2->data || oprr->next->data==0)
oprr->data='+';
else
oprr->data='-';
return OK;
}

//=====================================除法模块===========================================
//除法子函数
int idiv_sub(NodeList &opr1,NodeList opr2)
{
NodeList p1,p2,qh,qt,qq;
int count,CF,buffer,flag;
count=0;
while(compare(opr1,opr2)!=-1)
{
CF=buffer=0;
p1=opr1->prior;
p2=opr2->prior;
while(p2!=opr2)
{
if(p1->data<(p2->data+CF))
{
buffer=10000+p1->data-(p2->data+CF);
CF=1;
}
else
{
buffer=p1->data-(p2->data+CF);
CF=0;
}
p1->data=buffer;
p1=p1->prior;
p2=p2->prior;
}
if(p1!=opr1)//处理opr1链剩下的部份
{
buffer=p1->data-CF;
p1->data=buffer;
}

//清头0
flag=0;
p1=opr1->next;
while(p1->data==0 && p1->next!=opr1)
{
p1=p1->next;
flag=1;
}
if(flag)
{
qh=opr1->next;//保存无用结点的头尾指针
qt=p1->prior;//为释放做准备
opr1->next=p1;//重接next链
p1->prior=opr1;//重接prior链
qt->next=NULL;
while(qh!=NULL)
{//释放无用结点
qq=qh;
qh=qh->next;
free(qq);
}
}
count++;
}
return count;
}

//除法函数
Status idiv(NodeList opr1,NodeList opr2,NodeList &quti,NodeList &remand)
{//quti为商数链,remand为余数链
int len_quti,len_reman,buffer;
NodeList q1,q2,pq;
if(compare(opr1,opr2)==-1)
{//除数比被除数大
Creat(quti,1);
quti->

next->data=0;
quti->next->next=quti;
quti->prior=quti->next;
remand=opr1;
}
else
{
len_quti=length(opr1)-length(opr2);
len_reman=length(opr2);
Creat(quti,len_quti+1);//开辟商数链
Creat(remand,len_reman);//开辟余数链
q1=opr1->next;
q2=remand->next;
//初始化remand链
while(q2!=remand)
{
q2->data=q1->data;
q1=q1->next;
q2=q2->next;
}
pq=quti->next;
q1=q1->prior;//指针退回一步
while(q1!=opr1)
{
buffer=idiv_sub(remand,opr2);
pq->data=buffer;
if(q1->next!=opr1)
{
remand->prior->next=(NodeList)malloc(LEN);
remand->prior->next->next=remand;
remand->prior->next->prior=remand->prior;
remand->prior=remand->prior->next;
remand->prior->data=q1->next->data;
}
if(remand->next->data==0 && remand->next->next!=remand)
{
remand->next->next->prior=remand;
remand->next=remand->next->next;
}
q1=q1->next;
pq=pq->next;
}
pq=quti->prior;
while(pq->data=='?')
pq=pq->prior;
pq->next=quti;
quti->prior=pq;
}
if(opr1->data=='-' && remand->next->data!=0)
remand->data='-';
else
remand->data='+';
if(opr1->data==opr2->data || quti->next->data==0)
quti->data='+';
else
quti->data='-';
return OK;
}
//========================================================================================



//========================================主操作模块======================================
//
void title()
{
int i;
printf("\n");
for(i=0;i<33;i++)
printf("*");
printf("长整数四则运算");
for(i=0;i<33;i++)
printf("*");
}

//打印欢迎屏幕
void welcome()
{
printf("===============================================================================\n\n");
printf(" 欢迎使用长整数四则运算程序\n\n");
printf("请按如下提示进行操作:\n\n");
printf("首先,根据屏幕的提示选择您想进行的操作。\n\n");
printf("其次,根据提示输入两个操作数。\n\n");
printf("注意:请不要输入类似-0、0012、0X0d之类的操作数。否则程序会提示错误,请从新输入。\n");
printf(" 作者:XXX(xxxxxxXXXXXXXXXXXXXXXX)\n");
printf("============================================================
794
===================\n\n");
}

//主调用函数
Status main_do()
{
NodeList opr1,opr2,oprr,quti,remand;
char str[MAX],ch;//输入输出缓冲区
opr1=opr2=oprr=quti=remand=NULL;
title();
printf("输入1、2、3、4或5选择操作:\n");
printf(" 1、加法\n");
printf(" 2、减法\n");
printf(" 3、乘法\n");
printf(" 4、除法\n");
printf(" 5、退出\n");
printf(" 请选择:");
ch=getchar();
getchar();
while(ch>'5' || ch<'1')
{
printf("没有对应的操作项,请重新选择:");
ch=getchar();
getchar();
}
switch(ch)
{
case '1':input(opr1,opr2,

str);
printf("\n相加的和为:\n");
add(opr1,opr2,oprr);
if(!output(oprr,str))
printf("程序出错,抱歉!请检查输入的操作数是否正确。\n");
break;
case '2':input(opr1,opr2,str);
printf("\n相减的差为:\n");
sub(opr1,opr2,oprr);
if(!output(oprr,str))
printf("程序出错,抱歉!\n请检查输入的操作数是否正确。\n");
break;
case '3':input(opr1,opr2,str);
printf("\n相乘的积为:\n");
imul(opr1,opr2,oprr);
if(!output(oprr,str))
printf("程序出错,抱歉!\n请检查输入的操作数是否正确。\n");
break;
case '4':input(opr1,opr2,str);
while(opr2->next->data==0)
{
printf("除数不能为0!\n请重新输入:\n");
scanf("%s",str);
conversion(str,opr2);
}
idiv(opr1,opr2,quti,remand);
printf("\n商数为:\n");
if(!output(quti,str))
printf("程序出错,抱歉!\n请检查输入的操作数是否正确。\n");
printf("\n余数为:\n");
if(!output(remand,str))
printf("程序出错,抱歉!\n请检查输入的操作数是否正确。\n");
break;
case '5':exit(0);
}
return OK;
}

//主函数
int _tmain(int argc, _TCHAR* argv[])
{
int flag=1;
char ch;
system("color F0");
welcome();
printf("确认请按Enter键");
getchar();
system("cls");
while(flag)
{
main_do();
printf("\n继续?(Y/N)");
ch=getchar();
getchar();
if(ch=='N' || ch=='n')
flag=0;
system("cls");
}
return 0;

5
}


0


相关文档
最新文档