设计一个程序实现两个任意长的整数求和与差的运算
要用c语言编写,最好能有必要的文字说明。 展开
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//mat97
//以下是双链表的节点结构,每个节点存储一个4位的数,比如1,0031,0056存入链表后就是1,31,56三个节,输出的时候再补0输出!
typedef struct node{
int n;
struct node *next;
struct node *prev;
} node;
node *p;
char num1[1024],num2[1024];
int conv(char *a)
{
int n=0,i;
for(i=0;a[i];++i)
{
n*=10;
n+=(a[i]-'0');
}
return n;
}
int main()
{
char c[2];
int i,f;
node *q;
p=(node*)malloc(sizeof(node));
p->next=p->prev=0;
q=p;
num1[0]=num2[0]=',';
printf("Enter num 1:\n");
scanf("%s",num1+1);
for(i=strlen(num1);i>=0;--i)
{
if(num1[i]==',')
{
num1[i]=0;
q->next=(node*)malloc(sizeof(node));
q->next->prev=q;
q->next->next=0;
q=q->next;
q->n=conv(num1+i+1);
}
}
q->next=p;
p->prev=q;
printf("Enter op:\n");
scanf("%s",c);
*c=*c=='+'?0:1;
printf("Enter num 2:\n");
scanf("%s",num2+1);
q=p;f=0;
if(!*c) //+
{
for(i=strlen(num2);i>=0;--i)
{
if(num2[i]==',')
{
num2[i]=0;
if(q->next==p)
{
q->next=(node*)malloc(sizeof(node));
q->next->next=p;
q->next->prev=q;
q->next->n=0;
p->prev=q->next;
}
q=q->next;
q->n+=(conv(num2+i+1)+f);
if(q->n<10000)
f=0;
else
{
f=1;
q->n-=10000;
}
}
}
if(f)
{
if(q->next==p)
{
q->next=(node*)malloc(sizeof(node));
q->next->next=p;
q->next->prev=q;
q->next->n=1;
}
else
{
while(q->next!=p)
{
q=q->next;
q->n+=1;
if(q->n<10000)
{
f=0;
break;
}
else
{
q->n=0;
f=1;
}
}
if(f)
{
q->next=(node*)malloc(sizeof(node));
q->next->next=p;
q->next->prev=q;
q->next->n=1;
}
}
}
printf("%d,",p->prev->n);
for(q=p->prev->prev;q!=p;q=q->prev)
printf("%04d,",q->n);
}
else //-
{
for(i=strlen(num2);i>=0;--i)
{
if(num2[i]==',')
{
num2[i]=0;
if(q->next==p)
{
q->next=(node*)malloc(sizeof(node));
q->next->next=p;
q->next->prev=q;
q->next->n=0;
p->prev=q->next;
}
q=q->next;
q->n-=(conv(num2+i+1)+f);
if(q->n>=0)
f=0;
else
{
f=1;
q->n+=10000;
}
}
}
if(f)
{
if(q->next==p)
{
q->n-=10000;
}
else
{
while(q->next!=p)
{
q=q->next;
q->n-=1;
if(q->n>=0)
{
f=0;
break;
}
else
{
q->n+=10000;
f=1;
}
}
if(f)
{
q->n-=10000;
}
}
}
printf("%d,",p->prev->n);
for(q=p->prev->prev;q!=p;q=q->prev)
printf("%04d,",q->n);
}
return 0;
}
纯手打,已测试,楼主先看着,有不懂的再追问
加法:
减法:
编码辛苦,希望各位大神不要copy,小弟跪谢……
循环连别的节点这样定义:
struct Node{
int data;
Node * next;
Node * pre};
每个节点只保存小于10000的四位数,当两个长整数(也就是两个循环链表)相加的时候,
假设链表从低位到高位每四位保存到一个节点,那么就模拟加法的进位过程,两个链表的
对应节点相加,如果超过10000就向下一个节点进位,本节点只保留余数。
需要注意的是如果最后相加超过了最长链表的长度,加法的结果链表需要增加一个节点。
2.如果考虑加法的操作数有负数,设计要麻烦一些。
这个时候头结点要另外设计:
struct SNode{
char symbol;
Node * next;
Node * pre;}; 中间节点同上。
如果两个都是负数,可以调用1中的方法相加,但是最后结果要取负数,也就是symbol='-'。
如果一正一负,可以重新设计一个减法借位的过程,不过还有一个更好的方法。
联想到计算机中对负数加法的操作,使用了取补相加的方法。
我们可以借鉴这种思想,取(两个数中最长位数+1)为模。将负数链表每个节点取反(每个节点的模为10000,等效于9999-原值)再加一,然后把两个链表用1中的进位方法相加,如果结果中最后一个节点产生了进位,那么结果为正数,除了头结点置正无需再加额外操作。如果结果中最后一个节点没有进位,那么结果是负数,需要将头节点symbol置于负,并将链表每位取反再加一。