2. 两数相加
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
#include<bits/stdc++.h>
using namespace std;
//Definition for singly-linked list.
struct ListNode
{
int val;
struct ListNode *next;
};
/********************提交代码********************/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)
{
int i,j=0,ca=0,cb=0,cnt=0;
int *a=(int*)malloc(10000*sizeof(int));
int *b=(int*)malloc(10000*sizeof(int));
int *c=(int*)malloc(10000*sizeof(int));
int *res=(int*)malloc(10000*sizeof(int));
struct ListNode *ans;
struct ListNode *p=l1;
struct ListNode *q=l2;
while(p)//将链表中的数存入数组
{
a[ca++]=p->val;
p=p->next;
}
while(q)
{
b[cb++]=q->val;
q=q->next;
}
bool flag=false;
if(ca>cb)//第一个串比第二个串位数多
{
for(i=0; i<cb; ++i)//处理前面相同位数下的相加
{
int res=a[i]+b[i];
if(flag)//有进位要加
{
++res;
flag=false;
}
if(res>=10)//需要进位
{
flag=true;
c[cnt++]=res%10;
}
else
c[cnt++]=res%10;
}
j=cnt;
for(i=cb; i<ca; ++i)//处理多余位数
c[cnt++]=a[i];
while(flag)//处理相同位数下的进位
{
if(j==ca-1)
{
++c[j];
break;
}
++c[j];
flag=false;
if(c[j]>=10)
{
c[j]%=10;
flag=true;
++j;
}
}
}
else if(ca<cb)//第一个串比第二个串位数少
{
for(i=0; i<ca; ++i)
{
int res=a[i]+b[i];
if(flag)
{
++res;
flag=false;
}
if(res>=10)
{
flag=true;
c[cnt++]=res%10;
}
else
c[cnt++]=res%10;
}
j=cnt;
for(i=ca; i<cb; ++i)
c[cnt++]=b[i];
while(flag)
{
if(j==cb-1)
{
++c[j];
break;
}
++c[j];
flag=false;
if(c[j]>=10)
{
c[j]%=10;
flag=true;
++j;
}
}
}
else//相等位数
{
for(i=0; i<ca; ++i)
{
int res=a[i]+b[i];
if(flag)
{
++res;
flag=false;
}
if(res>=10)
{
flag=true;
c[cnt++]=res%10;
}
else
c[cnt++]=res%10;
}
if(flag)//处理最后一位的进位
{
c[cnt++]=1;
flag=false;
}
}
j=0;
for(i=0; i<cnt; ++i)
{
if(c[i]>=10)//处理二位数
{
res[j++]=c[i]%10;
res[j++]=c[i]/10;
}
else
res[j++]=c[i];
}
struct ListNode *s,*r;
ans=(struct ListNode *)malloc(sizeof(struct ListNode));
ans->val=res[0];
ans->next=NULL;
r=ans;
for(i=1; i<j; ++i)//尾插
{
s=(struct ListNode *)malloc(sizeof(struct ListNode));
s->val=res[i];
r->next=s;
r=s;
}
r->next=NULL;
return ans;
}
/***************************************************/
void Create(ListNode *&h,int a[],int n)//建立一个不带头节点的单链表
{
int i;
ListNode *s,*r;
h=(ListNode *)malloc(sizeof(ListNode));
h->val=a[0];
h->next=NULL;
r=h;
for(i=1; i<n; ++i)
{
s=(ListNode *)malloc(sizeof(ListNode));
s->val=a[i];
r->next=s;
r=s;
}
r->next=NULL;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("F:/cb/read.txt","r",stdin);
//freopen("F:/cb/out.txt","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int m,n;
while(cin>>m>>n)
{
struct ListNode *ans;
ListNode *l1,*l2;
int a[100],b[100];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0; i<m; ++i)
cin>>a[i];
Create(l1,a,m);//尾插法将a数组中的值插入链表
for(int i=0; i<n; ++i)
cin>>b[i];
Create(l2,b,n);
ans=addTwoNumbers(l1,l2);
struct ListNode *p=ans;
while(p)
{
cout<<p->val;
p=p->next;
}
cout<<endl;
}
return 0;
}
数据位数会比较长,所以不能先相加再存入新链表。
所以这其实就是两个大数相加的模拟题啦。
手生的很(;д;),这种函数链表也忘了(;′⌒`),我贼菜哇QAQ。
我是分成两个数位数长度的三种情况来讨论的,相同位上的数依次相加考虑进位就OK了。
测试用例:
2 2
9 9
9 9
2 2
3 7
9 2
3 3
2 4 3
5 6 4
1 3
1
9 9 9
3 1
8 9 9
2
3 1
9 9 9
1
1 3
0
2 7 8
1 2
1
9 9
2 1
9 8
1
2 1
1 8
0
1 2
0
1 8
3 3
2 4 3
5 6 4