#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;
}
程序设计周之大数加减
最新推荐文章于 2024-09-16 17:46:36 发布