程序设计周之大数加减

#include<iostream>
#include<fstream>
#include<string>
#include<windows.h>
#include<algorithm>
#include<iomanip>
#include <graphics.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
using namespace std;
#define MAXSTAR 400	// 星星总数
struct STAR
{
	double	x;
	int		y;
	double	step;
	int		color;
};
STAR star[MAXSTAR];
// 初始化星星
void InitStar(int i)
{
	star[i].x = 0;
	star[i].y = rand() % 480;
	star[i].step = (rand() % 5000) / 1000.0 + 1;
	star[i].color = (int)(star[i].step * 255 / 6.0 + 10000.0);	// 速度越快,颜色越亮
	star[i].color = RGB(star[i].color, star[i].color, star[i].color);
}
// 移动星星
void MoveStar(int i)
{
	// 擦掉原来的星星
	putpixel((int)star[i].x, star[i].y, 0);

	// 计算新位置
	star[i].x += star[i].step;
	if (star[i].x > 640)	InitStar(i);

	// 画新星星
	putpixel((int)star[i].x, star[i].y, star[i].color);
}
class BigNum
{
protected:
	string  num1, num2, num3, mod;
	int flag1;//用来记录符号位置
	char flag2;//用来记录符号
public:
	string ori;
	void FileInput();
	void FileOutput();
	void Input();
	void Judge1();//调用计算函数
	string Plus(const string& a,const string&b);
	string Sub(const string &a, const string& b);
	string Mult(const string& a, const string& b);
	string Div();
	void Output();
	char Judge2();//判断是否循环
	char Judge3();//判断输入方式
};
int main()
{
	srand((unsigned)time(NULL));
	int count = 0;
	initgraph(800, 500);// 创建绘图窗口
	// 初始化所有星星
	for (int i = 0; i < MAXSTAR; i++)
	{
		InitStar(i);
		star[i].x = rand() % 640;
	}
	// 绘制星空,按任意键退出
	while (count < 50)
	{
		for (int i = 0; i < MAXSTAR; i++)
			MoveStar(i);
		Sleep(20);
		count++;
	}
	settextstyle(60, 0, _T("隶书"));
	outtextxy(120, 200, _T("欢迎使用竖式计算器!"));//将字符串输出到界面上
	Sleep(1000);
	closegraph();
	BigNum C1;
	char jug3;
	mciSendString(_T("open 我的音乐.mp3"), NULL, 0, NULL);
	mciSendString(_T("play 我的音乐.mp3 repeat"), NULL, 0, NULL);
	do
	{
		jug3 = C1.Judge3();
		if (jug3 == 'P')
		{
			ifstream myfile("1.txt");
			ofstream outfile("2.txt", ios::app);
			if (!myfile.is_open())
			{
				cout << "未成功打开文件" << endl;
				break;
			}
			while (getline(myfile, C1.ori))
			{
				C1.FileInput();
				C1.Judge1();//计算结果
				C1.FileOutput();
			}
			myfile.close();
			outfile.close();
		}
		else if(jug3=='Q')
		{
			C1.Input();//输入算式
			C1.Judge1();//计算结果
			C1.Output();  //输出结果
		}
		else
		{
			cout << "输入有误\n";
		}
	} while (C1.Judge2() == 'Y');
	mciSendString(_T("close 我的音乐.mp3 repeat"), NULL, 0, NULL);
	return 0;
}
void BigNum::FileInput()
{
	int i;
	for (i = 0;i < ori.length();i++)
	{
		if (ori[i] > '9' || ori[i] < '0')
		{
			flag1 = i;//记录符号下标位置
			flag2 = ori[i];//记录符号
			break;
		}
	}
	num1 = ori.substr(0, flag1);//用num1提取第一个数字
	num2 = ori.substr(flag1 + 1, ori.length() -1- flag1-1 );//用num2提取第二个数字
}
void BigNum::Input()
{
	int i;
	cout << "请输入您要计算的式子(如:1+1=):\n";
	getline(cin, ori);
	for (i = 0;i < ori.length();i++)
	{
		if (ori[i] > '9' || ori[i] < '0')
		{
			flag1 = i;//记录符号位置
			flag2 = ori[i];//记录符号
			break;
		}
	}
	num1 = ori.substr(0, flag1);//用num1提取第一个数字
	num2 = ori.substr(flag1 + 1, ori.length() - flag1 - 2);//用num2提取第二个数字
}
void BigNum::Judge1()//调用计算函数
{
	if (flag2 == '+')
	{
		num3 = Plus(num1,num2);
	}
	else if (flag2 == '-')
	{
		num3 = Sub(num1,num2);
	}
	else if (flag2 == '*')
	{
		num3 = Mult(num1,num2);
	}
	else if (flag2 == '/')
	{
		if (num2 == "0")
		{
			num3 = "illegal input";
		}
		else
		{
			num3 = Div();
		}
	}
	else
	{
		num3 = "illegal input";
	}
}
string BigNum::Plus(const string& a,const string&b)
{
	string a1 = a;
	string b1 = b;
	string res;
	int carry = 0;
	for (int i = a1.size() - 1, j = b1.size() - 1;i >= 0 || j >= 0 || carry != 0;i--, j--)
	{
		int p1 = i >= 0 ? a1[i] - '0' : 0, p2 = j >= 0 ? b1[j] - '0' : 0;
		int k = p1 + p2 + carry;
		res.push_back(k % 10 + '0');
		carry = k / 10;
	}
	reverse(res.begin(), res.end());
	return res;
}
string BigNum::Sub(const string& a,const string& b)
{
	string ans;
	string  a1 = a, b1 = b;
	if (a1.compare(b1) == 0)
	{
		return "0";
	}
	else if (a1.size() > b1.size() || a1.size() == b1.size() && a1.compare(b1) == 1)
	{
		for (int i = a1.size() - 1, j = b1.size() - 1;i >= 0 || j >= 0;i--, j--)
		{
			int p1 = i >= 0 ? a1[i] - '0' : 0, p2 = j >= 0 ? b1[j] - '0' : 0;
			if (p1 < p2)
			{
				a1[i - 1]--;
				p1 += 10;
			}
			int k = p1 - p2;
			ans.push_back(k + '0');
		}
		reverse(ans.begin(), ans.end());
		ans.erase(0, ans.find_first_not_of("0"));
		return ans;
	}
	else
	{
		for (int i = a1.size() - 1, j = b1.size() - 1;i >= 0 || j >= 0;i--, j--)
		{
			int p1 = i >= 0 ? a1[i] - '0' : 0, p2 = j >= 0 ? b1[j] - '0' : 0;
			if (p2 < p1)
			{
				b1[j - 1]--;
				p2 += 10;
			}
			int k = p2 - p1;
			ans.push_back(k  + '0');
		}
		reverse(ans.begin(), ans.end());
		ans.erase(0, ans.find_first_not_of("0"));
		reverse(ans.begin(), ans.end());
		ans.push_back('-');
		reverse(ans.begin(), ans.end());
		return ans;
	}
}
string BigNum::Mult(const string&a,const string&b)
{
	int m = a.size(), n = b.size();
	string ans(n + m, '0');
	for (int i = m - 1;i >= 0;i--)
	{
		for (int j = n - 1;j >= 0;j--)//第一个数字的第i位和第二个数字的第j位相乘,结果存在i+j+1这一位
		{
			int  k = (a[i] - '0') * (b[j] - '0');
			int  t = k + (ans[i + j + 1] - '0');//加上上一次进位的
			ans[i + j] += t / 10;//进位
			ans[i + j + 1] = t % 10 + '0';
		}
	}
	ans.erase(0, ans.find_first_not_of("0"));
	return ans.empty() ? "0" : ans;
}
string BigNum::Div()
{
	string a = num1;
	string b = num2;
	string  ans(1, '0' - 1), sup;
	if (a==b)
	{
		return "1";
	}
	else if (a.size() < b.size() || a.size() == b.size() && a.compare(b) == -1)
	{
		return "0";
	}
	else
	{
		sup = a;
		for (int i = 0;sup[0]!='-';i++)
		{
			sup = Sub(sup,num2);
			ans = Plus(ans,"1");
		}
		return ans;
	}
}
void BigNum::Output()
{
	if (num3 == "illegal input")
	{
		cout << "输入有误,请重新输入\n";
		return;
	}
	if (flag2 == '/')
	{
			int m = num1.size();
			int n = num2.size();
			int k = num3.size();
			string temp1, temp2(1, '0'), temp3 = num1;
			cout << num1 << flag2 << num2 << "=" << num3 << "\n";//输出式子
			cout << setfill(' ') << setw(n + m + 1 + 10) << num3 << "\n";//n+m+1+10为右对齐位置
			cout << setfill(' ') << setw(n  + 10+1) <<'_' << setfill('_') << setw(m) << '_'<<"\n";
			cout << setfill(' ') << setw(10 + n) << num2 << ")" << num1 << "\n";
				for (int i = 0;i < k;i++)
				{
					temp2[0] = num3[i];
					temp1 = Mult(num2, temp2);
					cout << setfill(' ') << setw( n+m + 1 + 10+i-k+1) << temp1 <<"\n";//输出字符串
					cout << setfill(' ') << setw(n+1+10) << '_' << setfill('_') << setw(m) << '_' << "\n";
					if (i == 0)//第一次
					{
						temp3 = num1.substr(0, m - k +1);//被除数下标为0位置开始,提取到与num[i]位置对齐
					}
					temp3 = Sub(temp3, temp1);
					if (i != k - 1)//判断是否是最后一次
					{
						temp3.push_back(num1[m - k + i + 1]);
						cout << setfill(' ') << setw(n + m + 1 + 10 + i - k + 1 + 1) << temp3 << "\n";
					}
					else
					{
						cout << setfill(' ') << setw(n + m + 1 + 10) << temp3 << "\n";
					}
				}
				cout << "\n";
	}
	else if (flag2 == '*')
	{
		if (num2.size() > 1)
		{
			int x = num3.length(), y = x, count = 1, flag = 0, m, n;
			cout << num1 << flag2 << num2 << "=" << num3 << endl;
			cout << setw(x + 10) << num1 << endl;//x+10为右对齐长度
			cout << setfill(' ') << setw(6) << flag2 << setfill(' ') << setw(x + 4) << num2 << endl;
			cout << setfill('-') << setw(x + 15) << '-' << endl;
			m = num1.size(), n = num2.size();
			string temp1(n + m, '0'), ans, a, b;
			for (int j = n - 1;j >= 0;j--)
			{
				b = temp1;
				b.erase(0, b.find_first_not_of("0"));//b为上一次temp1的真实数字串
				if (b.size() == 0)//判断是否为0
				{
					b = "0";
				}
				for (int i = m - 1;i >= 0;i--)
				{
					int  k = (num1[i] - '0') * (num2[j] - '0');
					int  t = k + (temp1[i + j + 1] - '0');
					temp1[i + j] += t / 10;
					temp1[i + j + 1] = t % 10 + '0';
				}//temp1为每一位乘num1[i]的数字串相加,有前导0
				a = temp1;
				a.erase(0, a.find_first_not_of("0"));//删去前导0,a为每一位乘num1[i]的数字串相加的真实数字串
				if (a.size() == 0)//判断是否为0
				{
					a = "0";
				}
				ans = Sub(a, b);//需要输出的数,但末尾有多余0
				if (flag == 1)//flag为标记是否为第一次输出
				{
					if (ans != "0")
					{
						ans.erase(ans.size() - count, count);//删去末尾多余0个数,得到真实值
						count++;
						cout << setfill(' ') << setw(y + 10) << ans << "\n";
						y--;
					}
					else
					{
						count++;
						cout << setfill(' ') << setw(y + 10) << ans << "\n";
						y--;
					}
				}
				else//第一次输出末尾无多余0
				{
					flag = 1;
					cout << setfill(' ') << setw(y + 10) << ans << "\n";
					y--;
				}
			}
			cout << setfill('-') << setw(x + 15) << '-' << endl;
			cout << setfill(' ') << setw(x + 10) << num3 << "\n" << endl;
		}
		else//第二个乘数只有一位
		{
			int x = num3.length();//结果num3长度必最大
			cout << num1 << flag2 << num2 << "=" << num3 << endl;
			cout << setw(x + 10) << num1 << endl;
			cout << setfill(' ') << setw(6) << flag2 << setfill(' ') << setw(x + 4) << num2 << endl;
			cout << setfill('-') << setw(x + 15) << '-' << endl;
			cout << setfill(' ') << setw(x + 10) << num3 << "\n" << endl;
		}
	}
	else
	{
		int m;
		m = max(num1.length(), max(num2.length(), num3.length()));
		cout << num1 << flag2 << num2 << "=" << num3 << endl;
		cout << setw(m + 10) << num1 << endl;
		cout << setfill(' ') << setw(6) << flag2 << setfill(' ') << setw(m + 4) << num2 << endl;
		cout << setfill('-') << setw(m + 15) << '-' << endl;
		cout << setfill(' ') << setw(m + 10) << num3 << endl << endl;
	}
}
void BigNum::FileOutput()
{
	ifstream myfile("1.txt");
	ofstream outfile("2.txt", ios::app);
	if (flag2 == '/')
	{
		if (num3 == "illegal input")
		{
			outfile << num3 << "\n" << endl;
			myfile.close();
			outfile.close();
		}
		else
		{
			int m = num1.size();
			int n = num2.size();
			int k = num3.size();
			string temp1, temp2(1, '0'), temp3 = num1;
			outfile << num1 << flag2 << num2 << "=" << num3 << endl;
			outfile << setfill(' ') << setw(n + m + 1 + 10) << num3 << endl;
			outfile << setfill(' ') << setw(n + 10 + 1) << '_' << setfill('_') << setw(m) << '_' << "\n";
			outfile << setfill(' ') << setw(10 + n) << num2 << ")" << num1 << endl;
			for (int i = 0;i < k;i++)
			{
				temp2[0] = num3[i];
				temp1 = Mult(num2, temp2);
				outfile << setfill(' ') << setw(n + m + 1 + 10 + i - k + 1) << temp1 << endl;
				outfile << setfill(' ') << setw(n + 1 + 10) << '_' << setfill('_') << setw(m) << '_' << endl;
				if (i == 0)
				{
					temp3 = num1.substr(0, m - k + 1);
				}
				temp3 = Sub(temp3, temp1);
				if (i != k - 1)
				{
					temp3.push_back(num1[m - k + i + 1]);
					outfile << setfill(' ') << setw(n + m + 1 + 10 + i - k + 1 + 1) << temp3 << endl;
				}
				else
				{
					outfile << setfill(' ') << setw(n + m + 1 + 10 ) << temp3 << endl;
				}
			}
			outfile << endl;
			myfile.close();
			outfile.close();
		}
	}
	else if (flag2 == '*')
	{
		if (num2.size() > 1)
		{
			int x = num3.length(), y = x, count = 1, flag = 0, m, n;
			outfile << num1 << flag2 << num2 << "=" << num3 << endl;
			outfile << setw(x + 10) << num1 << endl;
			outfile << setfill(' ') << setw(6) << flag2 << setfill(' ') << setw(x + 4) << num2 << endl;
			outfile << setfill('-') << setw(x + 15) << '-' << endl;
			m = num1.size(), n = num2.size();
			string temp1(n + m, '0'),  ans, a, b;
			for (int j = n - 1;j >= 0;j--)
			{
				b = temp1;
				b.erase(0, b.find_first_not_of("0"));
				if (b.size() == 0)
				{
					b = "0";
				}
				for (int i = m - 1;i >= 0;i--)
				{
					int  k = (num1[i] - '0') * (num2[j] - '0');
					int  t = k + (temp1[i + j + 1] - '0');
					temp1[i + j] += t / 10;
					temp1[i + j + 1] = t % 10 + '0';
				}
				a = temp1;
				a.erase(0, a.find_first_not_of("0"));
				if (a.size() == 0)
				{
					a = "0";
				}
				ans = Sub(a, b);
				if (flag == 1)
				{
					if (ans != "0")
					{
						ans.erase(ans.size() - count, count);
						count++;
						outfile << setfill(' ') << setw(y + 10) << ans << "\n";
						y--;
					}
					else
					{
						count++;
						outfile << setfill(' ') << setw(y + 10) << ans << "\n";
						y--;
					}
				}
				else
				{
					flag = 1;
					outfile << setfill(' ') << setw(y + 10) << ans << "\n";
					y--;
				}
			}
			outfile << setfill('-') << setw(x + 15) << '-' << endl;
			outfile << setfill(' ') << setw(x + 10) << num3 << "\n" << endl;
			myfile.close();
			outfile.close();
		}
		else
		{
			int x = num3.length();
			outfile << num1 << flag2 << num2 << "=" << num3 << endl;
			outfile << setw(x + 10) << num1 << endl;
			outfile << setfill(' ') << setw(6) << flag2 << setfill(' ') << setw(x + 4) << num2 << endl;
			outfile << setfill('-') << setw(x + 15) << '-' << endl;
			outfile << setfill(' ') << setw(x + 10) << num3 << "\n" << endl;
			myfile.close();
			outfile.close();
		}
	}
	else
	{
		int m;
		m = max(num1.length(), max(num2.length(), num3.length()));
		outfile << num1 << flag2 << num2 << "=" << num3 << endl;
		outfile << setw(m + 10) << num1 << endl;
		outfile << setfill(' ') << setw(6) << flag2 << setfill(' ') << setw(m + 4) << num2 << endl;
		outfile << setfill('-') << setw(m + 15) << '-' << endl;
		outfile << setfill(' ') << setw(m + 10) << num3 << "\n" << endl;
		myfile.close();
		outfile.close();
	}
}
char BigNum::Judge2()
{
	char flag;
	string sup;
	cout << "是否继续计算(Y/N)?:" << endl;
	do
	{
		cout << "请输入:";
		cin >> flag;
		getline(cin, sup);
	} while (flag != 'Y' && flag != 'N');
	return flag;
}
char BigNum::Judge3()
{
	char judge;
	cout << "请选择输入方式:P(文本输入)Q(算式输入)\n";
	cin >> judge;
	getchar();
	return judge;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值