C语言大数加减

不多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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值