使用链表进行大数阶乘

@运用链表进行大数阶乘

运用链表进行大数阶乘

#include<iostream>
using namespace std;
struct Nums {											//链表结点类定义
	int data;											//链表结点数据
	Nums* lLink,*rLink;									//前驱,后继指针
	Nums(Nums* left = NULL, Nums* right = NULL)			//构造函数
	{
		lLink = left; rLink = right;
	}
	Nums(int na, Nums* left = NULL,Nums* right=NULL)	//构造函数
	{
		data = na; lLink = left; rLink = right;
	}
};

class Big_Data {										//大数运算的类定义
public:
	Big_Data();											//构造函数
	Big_Data(Big_Data& B);								//复制构造函数
	Nums* GetHead()const { return first; }				//获得双向循环链表的头指针
	Nums* GetLast()const {								//获得双向循环链表的尾指针
		return last;
	}									
	void Factor(int n);									//大数阶乘运算
	void Print();										//将大数阶乘的结果显示到屏幕上
private:
	Nums* first;										//双向链表的头指针
	Nums* last;											//双向链表的尾指针
};
Big_Data::Big_Data() {
	//构造函数,在头指针后增加新的结点,结点的数据为1。
	first = new Nums;
	if (first == NULL) { cerr << "存储分配出错!" << endl; exit(1); }
	Nums* newNode = new Nums(1);						//在头指针后插数据为1的结点
	first->rLink = first->lLink = newNode;
	newNode->rLink = newNode->lLink = first;
	last = newNode;										//尾指针设置为newNode
}
Big_Data::Big_Data(Big_Data& B) {
	//复制构造函数,用已有的大数对象B初始化当前大数。
	first = new Nums;
	if (first == NULL) { cerr << "存储分配出错!" << endl; exit(1); }
	Nums* destptr = first->rLink, * srcptr = B.GetHead()->rLink;
	while (srcptr != NULL) {
		destptr->data = srcptr->data;
		destptr->lLink = srcptr->lLink;
		destptr->rLink = srcptr->rLink;
		srcptr = srcptr->rLink;
	}
}
void Big_Data::Factor(int n) {
	//阶乘运算,输入n,从而计算n的阶乘
	int flag;											//flag设置为低位的进位
	for (int i = 1; i <= n; ++i) {
		flag = 0;										//每次循环设置为0
		Nums* current = first->rLink;
		while (current != first) {
			current->data = current->data * i + flag;	//当前的值乘i加上低位的进位flag就是当前结点应该取的值
			if (current->data > 999 && current->rLink == first) {
				//如果当前的数值大于999必须进位,如果后续结点为空需要添加一个新结点
				Nums* newNode = new Nums(0);			//新结点数据设为0
				newNode->rLink = current->rLink;
				current->rLink = newNode;
				newNode->lLink = first->lLink;
				first->lLink = newNode;
				last = newNode;							//last更新
			}
			flag = current->data / 1000;				//当前结点的数值对一千取商即为flag的值
			current->data = current->data % 1000;		//当前结点的数值对一千取余即为该结点应取的值
			current = current->rLink;					//切换到下一个结点,继续乘i
		}
	}
}
void Big_Data::Print() {
	//将阶乘所得的大数输出到屏幕上
	Nums* Last = GetLast();								//获取尾指针
	cout << Last->data;									//首先将尾指针的数据输出
	Nums* ptr = Last->lLink;
	while (ptr->lLink != Last) {						//利用双向链表反向遍历
		cout.fill('0');									//设置填充字符
		cout.width(3);									//设置域宽
		cout << ptr->data;								//将前面的结点的数据依次输出
		ptr = ptr->lLink;
	}
}

main函数

Big_Data b; int na;
	cout << "请输入要计算的数字:" << endl;
	cin >> na;
	b.Factor(na);
	cout << "n=" << na<<", n!=";
	b.Print();
	cout << endl;
	return 0;

运行结果
运行结果

欢迎各位交流指正。
未经本人允许请勿转载。

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值