长整数表示采用个位在链尾,高位在链头的方式。
由于正序做的时候处理单链表比较麻烦,所以想到用函数栈处理本位和,并向高位返回进位结果。总体时间复杂度为O(n)。
结构体:
typedef struct Node{
int data;
struct Node *next;
}*LongLink, Node;
初始化函数,直接输入长整数即可。
LongLink init(){
string s;
cin >> s;
int n = s.size();
LongLink head = new Node;
head->next = NULL;
LongLink p = head;
while(n--){
LongLink node = new Node;
node->data = char(s[s.size()-n-1]) - '0';
node->next = p->next;
p->next = node;
p = node;
}
return head;
}
实现两链表相加函数,由于题目要求结构体中不能保存链表长度,则需要手动扫描一遍链表计算长度,并且将更长的链表当作dfs的第一个参数。x是相加之后最高位的进位,如果有进位,则需要向高位插入一个结点。
LongLink addLong(LongLink L1, LongLink L2){
int n1=0, n2=0;
LongLink p1 = L1->next;
LongLink p2 = L2->next;
while(p1 != NULL){
n1++;
p1 = p1->next;
}
while(p2 != NULL){
n2++;
p2 = p2->next;
}
p1 = L1->next;
p2 = L2->next;
int x;
if(n1 < n2)
x = dfs(p2, p1, 1, 1, n2, n1);
else
x = dfs(p1, p2, 1, 1, n1, n2);
if(x == 1){
LongLink p = new Node;
p->data = x;
p->next = L1->next;
L1->next = p;
}
return L1;
}
主要功能函数,其中L表示当前的访问结点,i表示访问位置,n表示链表总长度。dfsAdd函数主要用来计算本位和以及进位的函数,dfs函数用递归的方式在函数栈最深时计算个位和,再将个位的进位通过函数返回的方式传给十位,以此类推。
int dfs(LongLink L1, LongLink L2, int i1, int i2, int n1, int n2){
if(L1 == NULL)
return 0;
if(i1 - i2 < n1 - n2)
return dfsAdd(L1, NULL, dfs(L1->next, L2, i1+1, i2, n1, n2));
return dfsAdd(L1, L2, dfs(L1->next, L2->next, i1+1, i2+1, n1, n2));
}
int dfsAdd(LongLink L1, LongLink L2, int x){
if(L2 == NULL){
L1->data += x;
int y = L1->data / 10;
L1->data %= 10;
return y;
}
else{
L1->data = L1->data + L2->data + x;
int y = L1->data / 10;
L1->data %= 10;
return y;
}
}
最终代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <exception>
#include <typeinfo>
#include <bits/stdc++.h>
using namespace std;
typedef struct Node{
int data;
struct Node *next;
}*LongLink, Node;
LongLink init(){
string s;
cin >> s;
int n = s.size();
LongLink head = new Node;
head->next = NULL;
LongLink p = head;
while(n--){
LongLink node = new Node;
node->data = char(s[s.size()-n-1]) - '0';
node->next = p->next;
p->next = node;
p = node;
}
return head;
}
int dfsAdd(LongLink L1, LongLink L2, int x){
if(L2 == NULL){
L1->data += x;
int y = L1->data / 10;
L1->data %= 10;
return y;
}
else{
L1->data = L1->data + L2->data + x;
int y = L1->data / 10;
L1->data %= 10;
return y;
}
}
int dfs(LongLink L1, LongLink L2, int i1, int i2, int n1, int n2){
if(L1 == NULL)
return 0;
if(i1 - i2 < n1 - n2)
return dfsAdd(L1, NULL, dfs(L1->next, L2, i1+1, i2, n1, n2));
return dfsAdd(L1, L2, dfs(L1->next, L2->next, i1+1, i2+1, n1, n2));
}
LongLink addLong(LongLink L1, LongLink L2){
int n1=0, n2=0;
LongLink p1 = L1->next;
LongLink p2 = L2->next;
while(p1 != NULL){
n1++;
p1 = p1->next;
}
while(p2 != NULL){
n2++;
p2 = p2->next;
}
p1 = L1->next;
p2 = L2->next;
int x;
if(n1 < n2)
x = dfs(p2, p1, 1, 1, n2, n1);
else
x = dfs(p1, p2, 1, 1, n1, n2);
if(x == 1){
LongLink p = new Node;
p->data = x;
p->next = L1->next;
L1->next = p;
}
return L1;
}
void output(LongLink head){
LongLink p = head->next;
while(p != NULL){
cout << p->data;
p = p->next;
}
cout << endl;
}
int main()
{
LongLink L1 = init();
LongLink L2 = init();
LongLink result = addLong(L1, L2);
output(result);
return 0;
}