加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

基于链表的四位存储大数计算

发布时间:2020-12-14 02:48:31 所属栏目:大数据 来源:网络整理
导读:数据结构的大型实验,和之前写的计算器不同的是,少了词法解析,多了链表指针操作,写完感觉,指针操作能力上了一个台阶,有时间有兴趣的亲,也可以尝试一下,下附实验报告及源码。 1. 实验内容 1.1 实验目的 实验通过实现基于链表类实现的大数类,从而锻炼

数据结构的大型实验,和之前写的计算器不同的是,少了词法解析,多了链表指针操作,写完感觉,指针操作能力上了一个台阶,有时间有兴趣的亲,也可以尝试一下,下附实验报告及源码。

1.实验内容

1.1实验目的

实验通过实现基于链表类实现的大数类,从而锻炼对链表的使用和有关大数的四则运算等操作,并在此过程中加深对类的理解和运用。

?

1.2类框架图

1.2.1 Node

Node类:


1.pre和next都是Node* 类型的指针,分别指向该节点的前驱和后继。

2.num存该节点的数值,大数类实现中采取四位存一个节点的方式,考虑到short的范围,故将数值设置为short类型。

3.Node()是此类的无参构造。



?

1.2.2 myList

myList类:

?

1.此类有first,tail,mySize三个数据成员,分别代表链表类的的头指针,尾指针和节点数(此链表带一个哨兵,哨兵不计节点数)。

2.myList()和myList(const&myList r)分别为无参构造函数和拷贝构造函数。

3.getSize()返回mySize的值。

4.add_back()和add_front()分别向链表后面和前面插入节点,向前插时,插在哨兵之后。

5.erase()删除尾指针指向的节点,当只剩哨兵时,不做操作。

6.display()因为是逆向存储的,故从后开始输出节点的值,特殊处理,第一个节点需去掉前置0。

7.~myList()析构函数,逐节点移动指针并释放内存。

?

?

?

?

?

1.2.3 BigInt


BigInt类:


1.BigInt类共3个数据成员,sign,data,digit。sign仅共一次减法运算的符号判断,data即用于存储的myList类。Digit是该大数的位数。

2.该类包含BigInt(),BigInt(strings),BigInt(const &BigInt r)3个构造函数。

3.display(ostream &out)函数用于输出,可以通过改变参数,灵活地进行控制台输出或文件输出。

4.operator系列,其它都没什么特殊,只是因为‘^’操作不宜过大,故将次数值限定在了long long int范围。

5.operator- 因为需要判断正负,故在类的设计上加上了sign,来表示正负。

6.结构图中遗漏了析构函数,~BigInt()通过显示调用data的析构函数进行析构。

?

?

1.3程序流程图


2.实验验证

2.1输入形式

程序开始,需输入指令选择文件输入或键盘输入,其后选择是文件输出,还是屏幕显示。之后,便可输入表达式,表达式的形式需为 a ? b ,‘?’代表运算符,a,b分别为两大数,两两之间以空格分隔。当全部运算结束,最后输入Ctrl+Z表示结束。

?

2.2输出形式

示例:

输入: 1 + 2

输出: Digit:1? BigInt:3

?

2.3程序功能

可以较快计算大整数的加减乘除模,同时可以较快计算大整数的long long int型幂次方。支持文件/键盘读入,文件输出/屏幕显示。

?

?

?

3.调试分析

3.1技术难点

1.采用四位为一节点逆序存储,虽然能很大程度上加快运算速率,但实现上也颇为复杂。

示例: 123456789?? 6789->2345->1

2.因为采用的是四位存储模式,需要分别更新大数的位数,和链表的节点数。虽然看似简单,但在实际调试中,因为需要及时更新位数,稍有遗漏就会对大数之间的大小比较产生影响,从而导致整个程序出错。

3.因为不能直接在链表基础上进行四则运算,需要在大数类上对链表进行操作,需通过增加节点,删除节点等操作间接运算,又因体系规模略显庞大,调试过程很容易出错。

4.在函数内生成对象,函数一结束就会被析构,因此需要定义全局变量,或动态生成。

5.因为要提高除法的效率,但又受四位存储的限制,不能直接通过增加节点来使除数有效地逼近被除数,只能先通过增加节点的方式最大限度使除数逼近被除数,然后再用除数乘以一个int型整数的方法逼近被除数,同时将以上过程实现为循环。

?

?

?

?

3.2技术问题及解决方案

Problem1:

乘法效率过低。

Solution1:

采用四位存储模式。

?

Problem2:

除法效率过低。

Solution2:

通过先不断给除数D的拷贝对象A增加0节点,并同时给初始值为1的大整数B增加0节点,再将A乘以一个小整数的方式,找到一个大致接近被除数C的值A,不断循环减去A,并同时在答案上加上B,直至C<A。在外层循环不断重复该过程,直至被除数C小于除数D。

?

Problem3:

求幂效率过低。

Solution3:

类比矩阵多次幂的思想,利用已计算好的较低次幂的乘积直接求得高次幂。具体实现:以十进制为单位,计算一个数的1次,10次,100次,并循环该位上对应的数值次,将答案乘以现乘积……直至与幂的最高位等位。最后乘积即为所求。

?

示例: 2^421

ans=1

//对应个位1

tmp=2^1=2? ans*=tmp

//对应十位2

tmp=2^10=(2^1)^10ans*=tmp ans*=tmp

//对应百位4

tmp=2^100=(2^10)^10ans*=tmp ans*=tmp ans*=tmp ans*=tmp

//最后ans即为所求。

??

Problem4:对象当函数调用完时,会被析构。

Solution4:使用全局变量,或者动态生成变量。

?

3.3调试错误及修正方案

1.写链表类erase()函数时,应把最后一个节点的后继置为NULL,但却因失误多打了一个‘=’,导致链表遍历时,始终无法终止。一直以为是端点处理有问题,最后将‘=’去掉,就顺利通过了。

2.写除法时,始终无法跳出循环,以为是>=重载出了问题,仔细调试后发现是因为>=是基于大数位数判断的,在计算过程中未能及时修正位数,导致>=判断始终成立。随后,在减法操作中不断更新位数,最后顺利跳出循环。

3.局部变量被析构,采取全局变量或者堆区的方法。???????

4.测试示例

4.1输入输出示例

1.文件输入,文件输出

?

?

?

2.文件输入,屏幕输出

?

?

3.控制台输入,屏幕输出

?

?

?

4.控制台输入,文件输出

?

?

4.2加法示例


4.3减法示例

?

?

4.4乘法示例

?

?

?

?

?

大数据测试时因控制台输入有限且不便,故采用文件流测试。此处可大致认为是两个10000位的数相乘,耗时4.6s。

?

4.5除法示例


4.6求幂示例


大数据测试(需考虑文件流输出稍慢):


?

4.7取模示例




4.源码及注释

//myList.h声明
#ifndef  MYLIST
#define MYLIST
#include <iostream>
using namespace std;
//Node类
class Node
{
public:
short num; //每四位存一节点
Node* pre;//指向该节点前驱
Node* next; //指向该节点后继
Node()//无参构造
{
num = 0;
next = NULL;
pre = NULL;
}
};
typedef  Node*  NodePointer;



class myList
{
public:
myList();
myList(const myList& rightHandSide);//拷贝构造
~myList();
int   getSize() const;
void add_back(int val);
void add_front(int val);
void display(ostream &out)const;//输出列表元素(遍历)
void erase();
myList  &operator =(const myList&  rightHandSide);
NodePointer tail;  //表尾指针
NodePointer first; //表首指针
private:
int mySize;
};
#endif // ! MYLIST
#include "myList.h"
#include <string>
myList::myList()
{
	first = new Node(); //默认一个哨兵节点
	tail = first;
	mySize = 0;
}
myList::myList(const myList& rightHandSide)
{
	    first = new Node();
		NodePointer tmp1=first;
		NodePointer tmp2=rightHandSide.first;
		NodePointer tmp3;
		mySize = rightHandSide.mySize;
		tmp2 = tmp2->next; 
//遍历rightHandSide逐节点拷贝
		while (tmp2 != NULL) 
		{
			tmp3 = new Node();
			tmp3->num = tmp2->num;
			tmp1->next = tmp3;
			tmp3->pre = tmp1;
			tmp1 = tmp3;
			tmp2 = tmp2->next;
		}
		tail = tmp1;
}
void myList::add_back(int val)//插入到链表尾部
{
	Node *newNode = new Node();
	newNode->num = val;
	newNode->pre = tail;
	(*tail).next = newNode;
	tail = newNode;
	mySize++;
}
void myList::add_front(int val)//插入在哨兵之后,现第一个节点之前
{
	Node *newNode = new Node();
	newNode->num = val;
	newNode->pre = first;
	if (first->next)(*first->next).pre = newNode;
	else tail = newNode;
	newNode->next = first->next;
	first->next = newNode;
	mySize++;
}
int myList::getSize() const
{
	return mySize;
}
void myList::display(ostream &out)const //遍历输出
{
	Node* tmp = tail;
	if (tmp != first)out << tmp->num;
	else return;
	tmp = tmp->pre;
	while (tmp != first)
	{
		int i = 0,temp = tmp->num;
		if (temp == 0)i = 1;//特殊情况处理,0视为1位
		while (temp)
		{
			temp /= 10;
			i++;
		}
		out << string(4 - i,'0'); //如果不是最后一个节点,输出时补0。
		out << tmp->num;
		tmp = tmp->pre;
	}
}
myList::~myList()//遍历析构
{
	Node *tmp;
	while (first)
	{
		tmp = first;
		first = first->next;
		delete tmp;
	}
}
void myList::erase()//删除最后一个节点
{
	if (mySize>0)
	{
		NodePointer tmp;
		tmp = tail;
		tail = tmp->pre;        
		delete tmp;
		tail->next = NULL;//就是此处调试了许久
		mySize--;
	}
}
myList & myList::  operator=(const myList&  rightHandSide)
{
	if (this == &rightHandSide)return *this;//排除自拷贝
	else
	{
		NodePointer tmp1 = first;
		NodePointer tmp2 = rightHandSide.first;
		NodePointer tmp3;
//比较大小,采取不同拷贝模式
		if (mySize >= rightHandSide.mySize)
		{
//先拷贝现有节点,再删除多余节点
			while (tmp2 != NULL)
			{
				tmp1->num = tmp2->num;
				if (tmp2->next == NULL)break;
				tmp2 = tmp2->next;
				tmp1 = tmp1->next;
			}
			tail = tmp1;
			tmp1 = tmp1->next;
			while (tmp1 != NULL)
			{
				tmp3 = tmp1;
				tmp1 = tmp1->next;
				delete tmp3;
			}
			tail->next = NULL;
		}
		else
		{
//先拷贝现有节点,再添加多余节点
			while (1)
			{
				tmp1->num = tmp2->num;
				if (tmp1->next == NULL)break;
				tmp2 = tmp2->next;
				tmp1 = tmp1->next;
			}
			while (1)
			{
				tmp2 = tmp2->next;
				if (tmp2 == NULL)break;
				tmp3 = new Node;
				tmp3->pre = tmp1;
				tmp3->num = tmp2->num;
				tmp1->next = tmp3;
				tmp1 = tmp3;
			}
			tail = tmp1;
		}
		mySize = rightHandSide.mySize;
		return *this;
	}
}





//BigInt.h
#ifndef BIGINT
#define BIGINT

#include<string>
#include"myList.h"
class BigInt
{
private:
	myList data;
	int digit;//大数位数
	bool sign;//只做为减法做一次判断
public:
	//构造函数
	BigInt();
	BigInt(string s);
	BigInt(const BigInt & x);
	//显示函数
	void display(ostream &out);
	//各类运算符重载
	BigInt &operator =(const BigInt &x);	
	BigInt  &operator +(const BigInt &x);
	BigInt  &operator -(const BigInt &x);
	bool operator >(const BigInt &x);
	bool operator >=(const BigInt &x);
	BigInt  &operator *(const BigInt &x);
	BigInt  &operator /(const BigInt &x);
	BigInt  &operator %(const BigInt &x);
	BigInt  &operator *(const int &x);
	BigInt  &operator ^(const long long int &x);
	//析构函数
	~BigInt();
	//更新位数
	void modifyDigit(BigInt &x);
};
#endif // !BIGINT









//BigInt.cpp
#include <algorithm>
#include <string>
#include"BigInt.h"
BigInt *replace1 = new BigInt();//全局变量
BigInt *replace2 = new BigInt();
BigInt *empty = new BigInt();//空节点
BigInt zero(string(1,'0'));//大数值为0,供函数使用
BigInt one(string(1,'1'));//大数值为1,供函数使用
//构造函数
BigInt::BigInt()
{
	myList();
	sign = false;
	digit = 0;
}
BigInt::BigInt(string s)
{
	myList();
	sign = false;
	digit = s.length();
	reverse(s.begin(),s.end());
/*每四位存一个节点,逆向存储,最前面不够的补0,方便统一转换*/
	int n = s.length() % 4;
	if (n != 0)
		s += string(4 - n,'0');
	int t = s.length() / 4;
	int tmp = 0;
	for (int i = 0; i < t; i++)
	{
		tmp = 0;
		tmp += s[i * 4] - '0';
		tmp += (s[i * 4 + 1] - '0') * 10;
		tmp += (s[i * 4 + 2] - '0') * 100;
		tmp += (s[i * 4 + 3] - '0') * 1000;
		data.add_back(tmp);
	}
}
BigInt::BigInt(const BigInt & x)
{
	sign = x.sign;
	data = x.data;
	digit = x.digit;
}
//操作符重载
BigInt & BigInt::operator =(const BigInt &x)
{
	sign = x.sign;
	data = x.data;
	digit = x.digit;
	return *this;
}
bool BigInt::operator >(const BigInt &x)
{
if (digit > x.digit)return true;//位数判断,因此计算过程中需不断修正
	else if (digit < x.digit)return false;
	else
	{
		NodePointer p1 = data.tail,p2 = x.data.tail;
		while (p1 != NULL)
		{
			if (p1->num > p2->num)return true;
			else if (p1->num < p2->num)return false;
			else
			{
				p1 = p1->pre;
				p2 = p2->pre;
			}
		}
		return false;//到这里说明相等
	}
}
bool BigInt::operator >=(const BigInt &x)
{
	if (digit > x.digit)return true;
	else if (digit < x.digit)return false;
	else
	{
		NodePointer p1 = data.tail,p2 = x.data.tail;
		while (p1 != NULL)
		{
			if (p1->num > p2->num)return true;
			else if (p1->num < p2->num)return false;
			else
			{
				p1 = p1->pre;
				p2 = p2->pre;
			}
		}
		return true;//到这里说明相等
	}
}
BigInt& BigInt:: operator +(const BigInt &x)
{
	*replace1 = *this;
	*replace2 = x;
	int t = data.getSize() - replace2->data.getSize();
	//将节点数补成相同
	if (t >= 0)
	{
		while (t)
		{
			replace2->data.add_back(0);
			t--;
		}
	}
	else
	{
		while (t)
		{
			replace1->data.add_back(0);
			t++;
		}
	}
	int flag = 0,tmp;
	NodePointer p1,p2;
	p1 = replace1->data.first;
	p2 = replace2->data.first;
	//删除前置0节点
	while (1)
	{
		if (p1->next == NULL)break;
		tmp = p1->num + p2->num + flag;
		p1->num = tmp % 10000;
		flag = tmp / 10000;
		p1 = p1->next;
		p2 = p2->next;
	}
	tmp = p1->num + p2->num+ flag;
	p1->num = tmp % 10000;
	if (tmp >= 10000)
		replace1->data.add_back(1); 
	//修正位数
	replace1->digit = (replace1->data.getSize() - 1) * 4;
	int lastNode = replace1->data.tail->num;
	if (lastNode < 10)replace1->digit += 1;
	else if (lastNode >= 10 && lastNode<100)replace1->digit += 2;
	else if (lastNode >= 100 && lastNode<1000)replace1->digit += 3;
	else replace1->digit += 4;
	return *replace1;
}
BigInt& BigInt:: operator -(const BigInt &x)
{
	*replace1 = *this;
	*replace2 = x;
	int t = replace1->data.getSize() - replace2->data.getSize();
	NodePointer p1,p2;//p1是大的那个数,p2是小的那个数
	bool symbol = false;//函数返回值是replace1还是replace2的标记
	if (*replace2 > *replace1)
	{
		replace2->sign = true;
		p1 = replace2->data.first;
		p2 = replace1->data.first;
	}
	else
	{
		symbol = true;
		p1 = replace1->data.first;
		p2 = replace2->data.first;
	}
	if (t >= 0)
	{
		while (t--)
		{
			replace2->data.add_back(0);
		}
	}
	else
	{
		while (t++)
		{
			replace1->data.add_back(0);
		}
	}
	int flag = 0,tmp;
	while (p1 != NULL)
	{
		tmp = p1->num - p2->num + flag;
		if (tmp < 0)
		{
			tmp += 10000;
			flag = -1;
		}
		else flag = 0;
		p1->num = tmp;
		p1 = p1->next;
		p2 = p2->next;
	}
	if (symbol)
	{
		p1 = replace1->data.tail;
		while (1)
		{
			if (p1->num != 0 || p1->pre == replace1->data.first)break;
			p1 = p1->pre;
			replace1->data.erase();
		}
		replace1->digit = (replace1->data.getSize() - 1) * 4;
		int lastNode = (*(replace1->data.tail)).num;
		if (lastNode < 10)replace1->digit += 1;
		else if (lastNode >= 10 && lastNode<100)replace1->digit += 2;
		else if (lastNode >= 100 && lastNode<1000)replace1->digit += 3;
		else replace1->digit += 4;
		return *replace1;
	}
	else
	{
		p1 = replace2->data.tail;
		while (1)
		{
			if (p1->num != 0 || p1->pre == replace2->data.first)break;
			p1 = p1->pre;
			replace2->data.erase();
		}
		replace2->digit = (replace2->data.getSize() - 1) * 4;
		int lastNode = (*(replace2->data.tail)).num;
		if (lastNode < 10)replace2->digit += 1;
		else if (lastNode >= 10 && lastNode<100)replace2->digit += 2;
		else if (lastNode >= 100 && lastNode<1000)replace2->digit += 3;
		else replace2->digit += 4;
		return *replace2;
	}
}
BigInt& BigInt:: operator *(const BigInt &x)
{
	//特判
		if (x.digit==1&&x.data.tail->num == 0)
		{
			BigInt *ans = new BigInt(zero);
			return *ans;
		}
		else if (x.digit == 1 && x.data.tail->num == 1)
		{
			BigInt *ans = new BigInt(*this);
			return *ans;
		}
		else
		{
			*replace1 = *empty;
			*replace2 = *empty;
			NodePointer p1,p2;
			p1 = this->data.first;
			int count = 0;
			while (1)
			{
				*replace2 = *empty;
				//乘法中的挪位
				for (int i = 0; i < count; i++)
				{
					replace2->data.add_back(0);
				}
				p1 = p1->next;
				if (p1 == NULL)break;
				p2 = x.data.first;
				int flag = 0,tmp1;
				while (1)
				{
					p2 = p2->next;
					if (p2 == NULL)break;
					tmp1 = p1->num * p2->num + flag;
					flag = tmp1 / 10000;
					tmp1 %= 10000;
					(*replace2).data.add_back(tmp1);
				}
				if(flag)/*此处有依据,9999*9999=99980001,就算再怎么进位,也只会多出一个节点*/
				{
					(*replace2).data.add_back(flag);
				}
				*replace1 = *replace1 + *replace2;
				count++;
			}
			return *replace1;
		}
}
BigInt& BigInt:: operator *(const int &x)
{
	*replace1 = *this;
	NodePointer p1;
	p1 = replace1->data.first;
	int flag = 0,tmp;
	while (1)
	{
		p1 = p1->next;
		if (p1 == NULL)break;
		tmp = (p1->num)*x + flag;
		flag = tmp / 10000;
		p1->num =(tmp)% 10000;
	}
	while (flag)
	{
		replace1->data.add_back(flag%10000);
		flag /= 10000;
	}
	replace1->digit = (replace1->data.getSize() - 1) * 4;
	tmp = (*(replace1->data.tail)).num;
	//修正位数
	if (tmp < 10)replace1->digit += 1;
	else if (tmp >= 10 && tmp<100)replace1->digit += 2;
	else if (tmp >= 100 && tmp<1000)replace1->digit += 3;
	else replace1->digit += 4;
	return *replace1;
}
BigInt& BigInt:: operator /(const BigInt &x)
{
	BigInt *divisor=new BigInt(x);
	BigInt *dividend = new BigInt(*this);
	//特判
	if (divisor->digit == 1 && divisor->data.tail->num == 1)
	{
		return *dividend;
	}
	else if (*divisor> *dividend)
	{
		BigInt *ans = new BigInt(zero);
		return *ans;
	}
	else 
	{
		BigInt *ans = new BigInt(*empty);
		ans->data.add_back(0);
		while ((*dividend)>=(*divisor))
		{
			BigInt tmp1(*divisor),tmp2(one);
			int count = dividend->digit - divisor->digit;
			count = (count - 1) / 4;
			//补节点0
			for (int i = 0; i < count; i++)
			{
				tmp1.data.add_front(0);
				tmp1.digit += 4;
				tmp2.data.add_front(0);
				tmp2.digit += 4;
			}
			int multi = 1;
			int t = (dividend->digit) - (tmp1.digit)-1;
			for (int i = 0; i < t; i++)
			{
				multi *= 10;
			}
			//继续逼近
			tmp1 = tmp1*multi;
			tmp2 = tmp2*multi;
			while ((*dividend)>=tmp1)
			{
				*ans = (*ans) + tmp2;
				*dividend = (*dividend) - tmp1;
			}
		}
		return *ans;
	}
}
BigInt& BigInt:: operator ^(const long long int &x)
{
	BigInt *tmp1 = new BigInt();
	BigInt *tmp2 = new BigInt();
	*tmp1 = *this;
	*tmp2 = *empty;
	tmp2->data.add_back(1);
	long long int store = x;
	int tmp;
	while (store)
	{
		tmp = store % 10;
		for (int i = 0; i < tmp; i++)
		{
			*tmp2 = (*tmp2)*(*tmp1);
		}
		*tmp1 = (*tmp1)*(*tmp1);
		BigInt temp(*tmp1);
		*tmp1 = (*tmp1)*(*tmp1);
		*tmp1 = (*tmp1)*(*tmp1);
		*tmp1 = *tmp1 * temp;
		store /= 10;
	}
	return *tmp2;
}
BigInt& BigInt:: operator %(const BigInt &x)
{
	BigInt *divisor = new BigInt(x);
	BigInt *dividend = new BigInt(*this);
	//特判
	if (divisor->digit == 1 && divisor->data.tail->num == 1)
	{
		BigInt *ans = new BigInt(zero);
		return *ans;
	}
	else if (*divisor> *dividend)
	{
		return *dividend;
	}
	else
	{
		while ((*dividend) >= (*divisor))
		{
			BigInt tmp1(*divisor);
			int count = dividend->digit - divisor->digit;
			count = (count - 1) / 4;
			//补节点0
			for (int i = 0; i < count; i++)
			{
				tmp1.data.add_front(0);
				tmp1.digit += 4;
			}
			int multi = 1;
			int t = (dividend->digit) - (tmp1.digit) - 1;
			for (int i = 0; i < t; i++)
			{
				multi *= 10;
			}
			//再继续逼近
			tmp1 = tmp1*multi;
			while ((*dividend) >= tmp1)
			{
				*dividend = (*dividend) - tmp1;
			}
		}
		return *dividend;
	}
}
void BigInt::display(ostream &out)
{
	out << "Digit is: " << digit;
	out << "   BigInt is: ";
	//sign正负标记
	if (sign)out << '-';
	data.display(out);
}
//位数修正
void BigInt::modifyDigit(BigInt &x)
{
	x.digit = (x.data.getSize() - 1) * 4;
	int lastNode = (*(x.data.tail)).num;
	if (lastNode < 10)x.digit += 1;
	else if (lastNode >= 10 && lastNode<100)x.digit += 2;
	else if (lastNode >= 100 && lastNode<1000)x.digit += 3;
	else x.digit += 4;
}
BigInt::~BigInt()
{
	data.~myList();
}


//main.cpp
#include "BigInt.h"
#include<iostream>
#include "stdio.h"
#include <time.h>
#include <fstream>
#include "windows.h"
//输入显示
void input_display()
{
	cout << "If you want to choose FileInput,please enter F/f.n";
	cout << "If you want to choose ConsoleInput,please enter C/c.n";
}
//输出显示
void out_display()
{
	cout << "If you want to choose FileOutput,please enter F/f.n";
	cout << "If you want to choose ScreenOutput,please enter S/s.n";
}
//string转long long int
long long int stringToInt(string s)
{
	long long int ans = 0,multi=1;
	for (int i = s.length() - 1; i >= 0; i--)
	{
		ans += multi*(s[i] - '0');
		multi *= 10;
	}
	return ans;
}
int main()
{
	char command;				
	string s1,s2;
	long long int c;
	char oper;
	clock_t start,end;
	string zero0 = "0";
	while (1)
	{
		input_display();
		cin >> command;
		//判断是控制台输入还是文件输入
		if (command == 'C' || command == 'c')
		{
			system("cls");
			out_display();
			cin >> command;
			system("cls");
			//判断是屏幕输出还是文件输出
			if (command == 'S' || command == 's')
			{

				while (cin >> s1 >> oper >> s2)
				{
					if (oper != '^')//区别^和其他运算符
					{
						BigInt a(s1),b(s2);
						start = clock();
						if (oper == '+')     b = a + b;
						else if (oper == '-')b = a - b;
						else if (oper == '*')b = a * b;
						else if (oper == '/')
						{
							if (s2 == zero0)
							{
								cout << "Error:  Divided by 0nn";
								continue;
							}
							else b = a / b;
						}
						else if (oper == '%')b = a % b;						
						else
						{
	cout << "Invalid operator.nOnly display the value of a and b:na:  ";
							a.display(cout);
							cout << endl<<"b:  ";
						}
						end = clock();
						b.display(cout);
						cout << endl;
			cout << "Calculation takes " << end - start << "msnn";
					}
					else
					{
						c = stringToInt(s2);
						BigInt a(s1);
						start = clock();
						a = a^c;
						end = clock();
						a.display(cout);
						cout << endl;
			cout << "Calculation takes " << end - start << "msnn";
					}
				}
			}
			else
			{
				string s1,s2,filename;
				long long int c;
				char oper;
				clock_t start,end;
				cout << "Please enter the name for the storage file!n";
				cin >> filename;
				filename += ".txt";//已处理后缀名
				ofstream fout(filename,ios::app);//输出文件流
				system("cls");
				while (cin >> s1 >> oper >> s2)
				{
					if (oper != '^')
					{
						BigInt a(s1),b(s2);
						start = clock();
						if (oper == '+')     b = a + b;
						else if (oper == '-')b = a - b;
						else if (oper == '*')b = a * b;
						else if (oper == '/')
						{
							if (s2 == zero0)
							{
								fout << "Error:  Divided by 0nn";
								continue;
							}
							b = a / b;
						}
						else if (oper == '%')b = a % b;
						else
						{
	fout << "Invalid operator.nOnly display the value of a and b:na:  ";
							a.display(fout);
							fout << endl << "b:  ";
						}
						end = clock();
						b.display(fout);
						fout << endl;
			fout << "Calculation takes " << end - start << "msnn";
						fout.flush();
					}
					else
					{
						c = stringToInt(s2);
						BigInt a(s1);
						start = clock();
						a = a^c;
						end = clock();
						a.display(fout);
						fout << endl;
			fout << "Calculation takes " << end - start << "msnn";
						fout.flush();
					}
				}
				fout.close();
			}
			break;
		}
		else if (command == 'F' || command == 'f')
		{
			system("cls");
			out_display();			
			cin >> command;
			if (command == 'F' || command == 'f')
			{
				system("cls");
				string filein,fileout;
				cout << "Please enter the calculate filenamen";
				cin >> filein;
				cout << "nPlease enter the storage filenamen";
				cin >> fileout;
				filein += ".txt";
				fileout += ".txt";
				ifstream fin(filein);
				ofstream fout(fileout);
				while (fin >> s1 >> oper >> s2)
				{
					if (oper != '^')
					{
						BigInt a(s1),b(s2);
						start = clock();
						if (oper == '+')     b = a + b;
						else if (oper == '-')b = a - b;
						else if (oper == '*')b = a * b;
						else if (oper == '/')
						{
							if (s2 == zero0)
							{
								fout << "Error:  Divided by 0nn";
								continue;
							}
							b = a / b;
						}
						else if (oper == '%')b = a % b;
						else
						{
	fout << "Invalid operator.nOnly display the value of a and b:na:  ";
							a.display(fout);
							fout << endl << "b:  ";
						}
						end = clock();
						b.display(fout);
						fout << endl;
			fout << "Calculation takes " << end - start << "msnn";
						fout.flush();
					}
					else
					{
						system("cls");
						c = stringToInt(s2);
						BigInt a(s1);
						start = clock();
						a = a^c;
						end = clock();
						a.display(fout);
						fout << endl;
				fout << "Calculation takes " << end - start << "msnn";
						fout.flush();
					}
				}
				fout.close();
				break;
			}
			else
			{
				string filein;
				cout << "Please enter the calculate filenamen";
				cin >> filein;
				filein += ".txt";
				ifstream fin(filein);
				while (fin >> s1 >> oper >> s2)
				{
					if (oper != '^')
					{
						BigInt a(s1),b(s2);
						start = clock();
						if (oper == '+')     b = a + b;
						else if (oper == '-')b = a - b;
						else if (oper == '*')b = a * b;
						else if (oper == '/')
						{
							if (s2 == zero0)
							{
								cout << "Error:  Divided by 0nn";
								continue;
							}
							b = a / b;
						}
						else if (oper == '%')b = a % b;
						else
						{
	cout << "Invalid operator.nOnly display the value of a and b:na:  ";
							a.display(cout);
							cout << endl << "b:  ";
						}
						end = clock();
						b.display(cout);
						cout << endl;
			cout << "Calculation takes " << end - start << "msnn";
					}
					else
					{
						c = stringToInt(s2);
						BigInt a(s1);
						start = clock();
						a = a^c;
						end = clock();
						a.display(cout);
						cout << endl;
			cout << "Calculation takes " << end - start << "msnn";
					}
				}
				break;
			}
		}
		else if (command == 'E' || command == 'e')//e退出
		{
			exit(0);
		}
		else
		{
			system("cls");
			cout << "Invalid Input!!!n";
		}
	}
	system("pause");
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读