线性表练习3——长整数四则运算

问题描述

在这里插入图片描述

解题思路

  • 每个节点中可以存放的最大整数为215-1,才能保证两数相加不会溢出,但若这样存放,即相当于按32768进制数存放,在书进制数与32768进制数之间的转换十分不方便,故可以在每个节点中仅存十进制数的4位,即不超过9999的非负整数
  • 可以利用头结点数据域的符号代表长整数的符号。用其绝对值表示元素结点数目。相加过程中不要破坏两个操作数链表。两个操作数的头指针存于指针数组中是简化程序结构的一种方法。不能给长整数位数规定上限

代码实现

  • 双向循环链表定义
typedef struct CNode
{
	ElemType data;
	struct CNode* last;
	struct CNode* next;
}CNode,*CLinkList;
  • 初始化双向循环链表
bool InitList(CLinkList &L,char *num)
{
	int i = 0;
	L = (CLinkList)malloc(sizeof(CNode));
	L->next = nullptr;
	L->last = nullptr;
	CNode* p = L;
	if (num[i] == '-')
	{
		L->data = 1;
		i++;
	}
	else
	{
		L->data = 0;
	}
	while (num[i] != '\0')
	{
		int k = 0;
		char tmp[nmax] = "";
		while (num[i] != ',' && num[i] != '\0')
		{
			tmp[k++] = num[i++];
		}
		int data = atoi(tmp);
		CNode* newNode = (CLinkList)malloc(sizeof(CNode));
		newNode->data = data;
		p->next = newNode;
		newNode->last = p;
		newNode->next = nullptr;
		p = newNode;
		if (num[i] == ',')
		{
			i++;
		}
		if (num[i] == '\0')
		{
			p->next = L;
			L->last = p;
			break;
		}
	}
	return true;
}
  • 输出链表
void showList(const CLinkList& L)
{
	CNode* q = L->next;
	int count = 0;
	for (; q != L; q = q->next)
		count+=q->data;
	if (!count)
	{
		cout << "0";
		return;
	}
	CNode* p = L->next;
	if(L->data==1)
		cout << '-';
	while (p->next != L)
	{
		if (p == L->next && p->data == 0) {}
		if (p != L->next && p->data == 0)
		{
			cout << "0000" << ",";
		}
		else
			cout << p->data << ",";
		p = p->next;
	}
	if (p->data != 0)
		cout << p->data;
	else
		cout << "0000";
}
  • 整数相减
void sublist(CLinkList& a, CLinkList& b)
{
	CNode* pa = a->last, * pb = b->last;
	//设置借位
	int borrow = 0;
	while (pb != b)
	{
		if (pa->data - pb->data - borrow >= 0)
		{
			pa->data = pa->data - pb->data - borrow;
		}
		else
		{
			pa->data = pa->data - pb->data - borrow + 10000;
			borrow = 1;
		}
		pa = pa->last;
		pb = pb->last;
	}
	if (pa == a && borrow == 1)
	{
		pa->last->data = 10000 - pa->last->data;
		if (a->data == 0)
			a->data = 1;
		else
			a->data = 0;
	}
	showList(a);
}
  • 整数相加
void addlist(CLinkList& a, CLinkList& b)
{
	CNode* pa = a->last, *pb = b->last;
	//设置进位标志
	int carry = 0;
	while (pb != b)
	{
		int data = (pa->data + pb->data+carry) % 10000;
		carry = (pa->data + pb->data + carry) / 10000;
		pa->data = data;
		pa = pa->last;
		pb = pb->last;
	}
	if (pa != a)
		pa->data += carry;
	else if(pa == a && carry)
	{
		CNode* newNode = (CLinkList)malloc(sizeof(CNode));
		newNode->data = carry;
		newNode->next = pa->next;
		pa->next->last = newNode;
		pa->next = newNode;
		newNode->last = pa;
	}
	showList(a);
}
  • 求链表长度
int length(const CLinkList &L)
{
	CNode* p = L->next;
	int len = 0;
	while (p!= L)
	{
		p = p->next;
		++len;
	}
	return len;
}
  • 主逻辑函数
void solve(CLinkList& a, CLinkList& b)
{
	if (a->data ^ b->data)
	{
		length(a) >= length(b) ? sublist(a, b) : sublist(b, a);
	}
	else
	{
		length(a) >= length(b) ? addlist(a, b) : addlist(b, a);
	}
}
  • 测试主函数
int main()
{
	char num1[nmax] = "";
	char num2[nmax] = "";
	cin.getline(num1, 1000);
	cin.getline(num2, 1000);
	CLinkList numlist1;
	CLinkList numlist2;
	InitList(numlist1, num1);
	InitList(numlist2, num2);
	solve(numlist1, numlist2);
	return 0;
}
  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值