课程题目:
设计一个程序实现两个任意长的整数求和运算。
要求:
利用双向循环链表实现长整数的存储,每个节点含有一个整型变量。 输入形式按照中国对于长整数的表示习惯,没四位一组,组间用逗号隔开。
思路:
为了达到上面的要求,我使用链表将长整数按照四位一组进行输入(每组用一个int表示就可以了)。然后对链表中的数字进行加法运算。
加法运算中心思想:先比较长度,以确定哪个数减去哪个数。组与组之间采用万进制,并且设立进位数,借位数,从而实现以上要求。
代码如下:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <math.h>
typedef int DataType;
//------------------
/*定义节点*/
typedef struct Node
{
int data;
struct Node* prior;
struct Node* next;
}DSLNode;
#include <malloc.h>
#include <stdlib.h>
#include <math.h>
typedef int DataType;
//------------------
/*定义节点*/
typedef struct Node
{
int data;
struct Node* prior;
struct Node* next;
}DSLNode;
//------------------
/*循环双向链表的初始化*/
void ListInisiate(DSLNode **head)
{
if((*head=(DSLNode *)malloc(sizeof(DSLNode)))==NULL)exit(0);
(*head)->prior=*head;
(*head)->next=*head;
//return 1;
}
//------------------
/*插入运算*/
int ListInsert(DSLNode *head,int i,DataType x)
{
DSLNode *p,*s;
int j;
p=head->next;
j=0;
while(p!=head&&j<i)
{
p=p->next;
j++;
}
if(j!=i)
{
printf("插入位置参数不合法/n");
return 0;
}
if((s=(DSLNode *)malloc(sizeof(DSLNode)))==NULL)exit(0);
s->data=x;
/*循环双向链表的初始化*/
void ListInisiate(DSLNode **head)
{
if((*head=(DSLNode *)malloc(sizeof(DSLNode)))==NULL)exit(0);
(*head)->prior=*head;
(*head)->next=*head;
//return 1;
}
//------------------
/*插入运算*/
int ListInsert(DSLNode *head,int i,DataType x)
{
DSLNode *p,*s;
int j;
p=head->next;
j=0;
while(p!=head&&j<i)
{
p=p->next;
j++;
}
if(j!=i)
{
printf("插入位置参数不合法/n");
return 0;
}
if((s=(DSLNode *)malloc(sizeof(DSLNode)))==NULL)exit(0);
s->data=x;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
return 1;
}
//--------------------------
/*求当前循环双向链表的长度*/
int ListLength(DSLNode *head)
{
DSLNode *p=head;
int length=0;
while(p->next!=head)
{
length++;
p=p->next;
}
return length;
}
p->prior->next=s;
s->next=p;
p->prior=s;
return 1;
}
//--------------------------
/*求当前循环双向链表的长度*/
int ListLength(DSLNode *head)
{
DSLNode *p=head;
int length=0;
while(p->next!=head)
{
length++;
p=p->next;
}
return length;
}
//-------------------
/*读取输入的数字*/
int InputNumber(DSLNode *head)
{
int input,i=0;
char c;
//读入数据时负数用0表示符号,正数用1表示符号
scanf("%d%c",&input,&c);
while(1)
{
if(input<0&&i==0)
{
head->data=0;
input=fabs(input);
ListInsert(head,i,input);
}
else if(input>=0&&i==0)
{
head->data=1;
ListInsert(head,i,input);
}
else ListInsert(head,i,input);
i++;
if(c==';')break;
scanf("%d%c",&input,&c);
}
return 1;
}
//-------------------
/*从表尾输出数据元素*/
void OutPutNumber(DSLNode *head,int sign)
{
DSLNode *head_3=head->prior;
//下面的if else是为了判断输出的正负号
if(sign==1)
printf("The result is:");
else
printf("The result is:-");
printf("%d",head_3->data);
head_3=head_3->prior;
while(head_3!=head)
{
if(head_3->data<10)
{
printf(",000");
printf("%d",head_3->data);
}
else if(head_3->data<100)
{
printf(",00");
printf("%d",head_3->data);
}
else if(head_3->data<1000)
{
printf(",0");
printf("%d",head_3->data);
}
else
printf(",%d",head_3->data);
head_3=head_3->prior;
}
printf("/n/n");
}
//------------------
/*长整数的加运算*/
int LongIntAdd(DSLNode *head1,DSLNode *head2,DSLNode *head3)
{
int data,i=0,length1,length2,mark,carry=0,brrow=0;//mark用于标记在异号情况下哪个一个更长些,carry用于标记进位
DSLNode *p=head1->next,*q=head2->next,*head_3=head3->prior,*notsame;
if(head1->data!=head2->data)//异号的运算
{
i=0;
length1=ListLength(head1);
length2=ListLength(head2);
if(length1==length2)
{//p和q节点个数相同的情况
while(p!=head1)
{//找出p和q中第一个节点数据不相同的节点
if(p->data>q->data)
{//p的值大于q的值
mark=1;
notsame=p->prior;
break;
}
else if(p->data<q->data)
{//q的值大于的p值
mark=2;
notsame=q->prior;
break;
}
else{//q->data等于p->data,指针继续往下移
p=p->next;
q=q->next;
}
}
if(p==head1)//一直到了表尾还是相同,则说明这两个数相同
{
printf("The result is:0/n");
return 0;
}
else if(mark==1)
{//p的值大于q的值
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(p!=notsame)
{//将p和q相应节点上的数相减
data=p->data-q->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
OutPutNumber(head3,head1->data);
}
else if(mark==2)
{//q的值大于p的值
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(q!=notsame)
{//将p和q相应节点上的数相减
data=q->data-p->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
q=q->prior;
p=p->prior;
}
OutPutNumber(head3,head2->data);
}
}
else if(length1>length2)
{//p的值比q的值大
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(q!=head2)
{//将p和q相应节点上的数相减
data=p->data-q->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
while(p!=head1)
{
data=p->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
if(p==head1->next)
{
if(data!=0)
ListInsert(head3,i,data);
}
else
ListInsert(head3,i,data);
p=p->prior;
i++;
}
OutPutNumber(head3,head1->data);
}
else if(length1<length2)
{//q的值比p的值大
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(p!=head1)
{//将p和q相应节点上的数相减
data=q->data-p->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
while(q!=head2)
{
data=q->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
if(q==head2->next)
{
if(data!=0)
ListInsert(head3,i,data);
}
else
ListInsert(head3,i,data);
q=q->prior;
i++;
}
OutPutNumber(head3,head2->data);
}
}
else //同号的情况
{
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(p!=head1&&q!=head2)
{
data=p->data+q->data+carry;
carry=0;//用完进位后要及时清零
if(data>9999)
{
carry=data/10000;
data%=10000;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
if(p==head1&&q==head2)//等长的情况
{
if(carry!=0)//有进位
{
ListInsert(head3,i,carry);
carry=0;
i++;
}
OutPutNumber(head3,head2->data);
}
else if(p==head1) //q的长度大于p的长度
{
if(carry!=0)//有进位
{
while(q!=head2)
{
data=q->data+carry;
carry=0;//用完进位后要及时清零
if(data>9999)
{
carry=data/10000;
data%=10000;
}
ListInsert(head3,i,data);
i++;
q=q->prior;
}
if(carry!=0)//有进位
{
ListInsert(head3,i,carry);
carry=0;
i++;
}
OutPutNumber(head3,head2->data);
}
else//无进位
{
while(q!=head2)
{
ListInsert(head3,i,q->data);
i++;
q=q->prior;
}
OutPutNumber(head3,head2->data);
}
}
else//p的长度大于q的长度
{
if(carry!=0)//有进位
{
while(p!=head1)
{
data=p->data+carry;
carry=0;
if(data>9999)
{
carry=data/10000;
data%=10000;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
}
if(carry!=0)//有进位
{
ListInsert(head3,i,carry);
carry=0;
i++;
}
OutPutNumber(head3,head2->data);
}
else//没有进位
{
while(p!=head1)
{
ListInsert(head3,i,p->data);
i++;
p=p->prior;
}
OutPutNumber(head3,head1->data);
}
}
/*读取输入的数字*/
int InputNumber(DSLNode *head)
{
int input,i=0;
char c;
//读入数据时负数用0表示符号,正数用1表示符号
scanf("%d%c",&input,&c);
while(1)
{
if(input<0&&i==0)
{
head->data=0;
input=fabs(input);
ListInsert(head,i,input);
}
else if(input>=0&&i==0)
{
head->data=1;
ListInsert(head,i,input);
}
else ListInsert(head,i,input);
i++;
if(c==';')break;
scanf("%d%c",&input,&c);
}
return 1;
}
//-------------------
/*从表尾输出数据元素*/
void OutPutNumber(DSLNode *head,int sign)
{
DSLNode *head_3=head->prior;
//下面的if else是为了判断输出的正负号
if(sign==1)
printf("The result is:");
else
printf("The result is:-");
printf("%d",head_3->data);
head_3=head_3->prior;
while(head_3!=head)
{
if(head_3->data<10)
{
printf(",000");
printf("%d",head_3->data);
}
else if(head_3->data<100)
{
printf(",00");
printf("%d",head_3->data);
}
else if(head_3->data<1000)
{
printf(",0");
printf("%d",head_3->data);
}
else
printf(",%d",head_3->data);
head_3=head_3->prior;
}
printf("/n/n");
}
//------------------
/*长整数的加运算*/
int LongIntAdd(DSLNode *head1,DSLNode *head2,DSLNode *head3)
{
int data,i=0,length1,length2,mark,carry=0,brrow=0;//mark用于标记在异号情况下哪个一个更长些,carry用于标记进位
DSLNode *p=head1->next,*q=head2->next,*head_3=head3->prior,*notsame;
if(head1->data!=head2->data)//异号的运算
{
i=0;
length1=ListLength(head1);
length2=ListLength(head2);
if(length1==length2)
{//p和q节点个数相同的情况
while(p!=head1)
{//找出p和q中第一个节点数据不相同的节点
if(p->data>q->data)
{//p的值大于q的值
mark=1;
notsame=p->prior;
break;
}
else if(p->data<q->data)
{//q的值大于的p值
mark=2;
notsame=q->prior;
break;
}
else{//q->data等于p->data,指针继续往下移
p=p->next;
q=q->next;
}
}
if(p==head1)//一直到了表尾还是相同,则说明这两个数相同
{
printf("The result is:0/n");
return 0;
}
else if(mark==1)
{//p的值大于q的值
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(p!=notsame)
{//将p和q相应节点上的数相减
data=p->data-q->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
OutPutNumber(head3,head1->data);
}
else if(mark==2)
{//q的值大于p的值
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(q!=notsame)
{//将p和q相应节点上的数相减
data=q->data-p->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
q=q->prior;
p=p->prior;
}
OutPutNumber(head3,head2->data);
}
}
else if(length1>length2)
{//p的值比q的值大
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(q!=head2)
{//将p和q相应节点上的数相减
data=p->data-q->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
while(p!=head1)
{
data=p->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
if(p==head1->next)
{
if(data!=0)
ListInsert(head3,i,data);
}
else
ListInsert(head3,i,data);
p=p->prior;
i++;
}
OutPutNumber(head3,head1->data);
}
else if(length1<length2)
{//q的值比p的值大
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(p!=head1)
{//将p和q相应节点上的数相减
data=q->data-p->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
while(q!=head2)
{
data=q->data+brrow;
brrow=0;
if(data<0)
{
data+=10000;
brrow=-1;
}
if(q==head2->next)
{
if(data!=0)
ListInsert(head3,i,data);
}
else
ListInsert(head3,i,data);
q=q->prior;
i++;
}
OutPutNumber(head3,head2->data);
}
}
else //同号的情况
{
while(q->next!=head2)
q=q->next;//将链表的当前指针指到表尾
while(p->next!=head1)
p=p->next;//将链表的当前指针指到表尾
while(p!=head1&&q!=head2)
{
data=p->data+q->data+carry;
carry=0;//用完进位后要及时清零
if(data>9999)
{
carry=data/10000;
data%=10000;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
q=q->prior;
}
if(p==head1&&q==head2)//等长的情况
{
if(carry!=0)//有进位
{
ListInsert(head3,i,carry);
carry=0;
i++;
}
OutPutNumber(head3,head2->data);
}
else if(p==head1) //q的长度大于p的长度
{
if(carry!=0)//有进位
{
while(q!=head2)
{
data=q->data+carry;
carry=0;//用完进位后要及时清零
if(data>9999)
{
carry=data/10000;
data%=10000;
}
ListInsert(head3,i,data);
i++;
q=q->prior;
}
if(carry!=0)//有进位
{
ListInsert(head3,i,carry);
carry=0;
i++;
}
OutPutNumber(head3,head2->data);
}
else//无进位
{
while(q!=head2)
{
ListInsert(head3,i,q->data);
i++;
q=q->prior;
}
OutPutNumber(head3,head2->data);
}
}
else//p的长度大于q的长度
{
if(carry!=0)//有进位
{
while(p!=head1)
{
data=p->data+carry;
carry=0;
if(data>9999)
{
carry=data/10000;
data%=10000;
}
ListInsert(head3,i,data);
i++;
p=p->prior;
}
if(carry!=0)//有进位
{
ListInsert(head3,i,carry);
carry=0;
i++;
}
OutPutNumber(head3,head2->data);
}
else//没有进位
{
while(p!=head1)
{
ListInsert(head3,i,p->data);
i++;
p=p->prior;
}
OutPutNumber(head3,head1->data);
}
}
}
return 1;
}
return 1;
}
int main()
{
int i=0;
DSLNode *head1,*head2,*head3;
for(i=0;i<10;i++)
{
ListInisiate(&head1);
ListInisiate(&head2);
ListInisiate(&head3);
printf("Please input the numbers:/n");
InputNumber(head1);
InputNumber(head2);
LongIntAdd(head1,head2,head3);
}
}