不多BB直接上代码
仅保留了相关函数
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef int ElemType;
typedef struct node {
ElemType data;
struct node* next;
}*List, *pNode, Node;
int length(List& L) {
pNode p = L->next;
int l = 0;
for (l; p; p = p->next, l++);
return l;
}
int init(List& L) {
L = (List)malloc(sizeof(Node));
if (!L) return -1;
L->next = NULL;
L->data = NULL;
return 1;
}
void create_head(List& L, ElemType values[], int length) {
int i = 0;
pNode p;
for (int i = 0; i < length; i++) {
init(p);
p->data = values[i];
p->next = L->next;
L->next = p;
}
}
void print(const char* info, List& L) {
puts(info);
if (!L) return;
pNode p = L->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
void printResult(const char* info, List& L) {
printf("%s ", info);
pNode p = L->next;
// 跳过前面的 0
while (p->data == 0) {
p = p->next;
}
while (p) {
printf("%d", p->data);
p = p->next;
}
printf("\n");
}
// 尾插法
void create_tail(List& L, ElemType values[], int length) {
pNode p = L, x;
for (int i = 0; i < length; i++) {
init(x);
x->data = values[i];
x->next = p->next;
p->next = x;
p = x;
}
p->next = NULL;
}
// 相减
List doSub(List& A, List& B) {
int carry = 0; // 是否产生进位
List C;
init(C);
pNode pa = A->next, pb = B->next, x;
while (pa || pb) {
if (!pa) break;
// -carry 是减的上一步的借位
int diff = pa->data - (pb ? pb->data : 0) - carry;
carry = diff < 0;
diff += 10 * carry;
// 头插,省一步reverse(C)
init(x);
x->data = diff;
x->next = C->next;
C->next = x;
// 移动
pa = pa ? pa->next : NULL;
pb = pb ? pb->next : NULL;
}
return C;
}
List sub(List& A, List& B) {
// 确保是大减小
if (length(A) > length(B))
return doSub(A, B);
else if (length(A) == length(B)) {
if (A->next->data > B->next->data)
return doSub(A, B);
return doSub(B, A);
}
else return doSub(B, A);
}
// 相加
List doAdd(List& A, List& B) {
int carry = 0;
List C;
init(C);
pNode pa = A->next, pb = B->next, x;
while (pa || pb) {
if (!pa) break;
// + carry是加的上一步的进位
int sum = pa->data + (pb ? pb->data : 0) + carry;
carry = sum >= 10;//发生进位的情况
sum %= 10;
// 头插
init(x);
x->data = sum;
x->next = C->next;
C->next = x;
pa = pa ? pa->next : NULL;
pb = pb ? pb->next : NULL;
}
// 最多一定只能超出一位。如9+9=18
if (carry) {
init(x);
x->data = carry;
x->next = C->next;
C->next = x;
}
return C;
}
List add(List& A, List& B) {
// 保证较长的数在左边(会关联到循环时对指针的判断)
return length(A) >= length(B) ? doAdd(A, B) : doAdd(B, A);
}
int main() {
#pragma region 相减
List LA, LB;
init(LA); init(LB);
// 数A=60008021496575314621
int A[] = { 6,0,0,0,8,0,2,1,4,9,6,5,7,5,3,1,4,6,2,1 };
int B[] = { 5,9,9,9,9,5,6,9,7,4,3,5,8,1,4 };
// 去前17位作为数A
create_head(LA, A, 17);
create_head(LB, B, 15);
for (int i = 0; i < 17; printf("%d", A[i++]));
printf(" - ");
for (int i = 0; i < 15; printf("%d", B[i++]));
List LC = sub(LA, LB);
printResult("\nA-B = ", LC);
#pragma endregion
printf("-------------------------\n");
#pragma region 相加
List LD, LE;
init(LD); init(LE);
int D[] = { 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 };
int E[] = { 8,9,6,8,4,1,9,3,9,9,2,5,9,7,9 };
create_head(LD, D, 15);
create_head(LE, E, 15);
for (int i = 0; i < 15; printf("%d", D[i++]));
printf(" + ");
for (int i = 0; i < 15; printf("%d", E[i++]));
List LF = add(LD, LE);
printResult("\nE+D = ", LF);
#pragma endregion
return (0);
}