第二次作业
GIT地址 | https://github.com/haozhenkai/Calculator |
GIT用户名 | haozhenkai |
学号后五位 | 61122 |
博客地址 | https://i.cnblogs.com/EditPosts.aspx?opt=1 |
作业链接 | https://www.cnblogs.com/harry240/p/11515697.html |
Part1.环境配置
下载vs2017以及安装等
使用c++的安装应用
GIt:
按照流程下载了GIT,花了比较久的时间来了解GIT.表示比较难。当然了,自己也比较笨。并申请了自己的账号等;
代码设计思路:
方法: code and fix
a.算式的产生;
x 运算符 y 运算符 z=
x,y,z 采用rand函数 rand%100 随机产生 0-100的三个整数
运算用j,k来代表 同样采用1+rand%4 随机产生1,2,3,4分别代表加减乘除;
b.对于不同情况出现的问题
由于采用的code and fix模式,对于预估的问题没有充分考虑
Q1 字符 #define char op1 *;这样的宏定义op1 只是代表*,并不能当做运算符进行使用。
而且目标结果的情况并不复杂4*4=16 且代码重复率很高。便采用了if(j= &&k= )的方式进行讨论
全部代码:
头文件:
#pragma once
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#pragma region MainFunc
bool CheckQuestion(string Question);
void Clear();//清空栈
void Calculate(string Question);
void UserGUI(string user_answer);
string Transform(int data);//将数值转换为字符串
#pragma endregion
bool CheckQuestion(string Question);
void Clear();//清空栈
void Calculate(string Question);
void UserGUI(string user_answer);
string Transform(int data);//将数值转换为字符串
#pragma endregion
#pragma region Integer
void ReadInt(string Question);
void Integer();//+-*/^
void CalInt();//确保Operator栈为空
string ToPower(string Question);//将 ** 转换为 ^
#pragma endregion
void ReadInt(string Question);
void Integer();//+-*/^
void CalInt();//确保Operator栈为空
string ToPower(string Question);//将 ** 转换为 ^
#pragma endregion
#pragma region Fraction
void ReadFraction(string Question);
int gcd(int x, int y);//最大因约数
int lcm(int x, int y);//最小公倍数 = 两数相乘 / 最大因约数
void Fraction();//+-*/
void CalFraction();
void Simple();//分数最简化
#pragma endregion
void ReadFraction(string Question);
int gcd(int x, int y);//最大因约数
int lcm(int x, int y);//最小公倍数 = 两数相乘 / 最大因约数
void Fraction();//+-*/
void CalFraction();
void Simple();//分数最简化
#pragma endregion
源文件
#include"stdafx.h"
#include"Calculate.h"
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
#include<fstream>
#include<math.h>
#include"Calculate.h"
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
#include<fstream>
#include<math.h>
using namespace std;
stack<long long int> Data; //数字
stack<char> Operator;
stack<long long int> Numerator;//分子
stack<long long int> Denominator;//分母
string result;
int PowModel = 0;//默认乘方为 ^
stack<char> Operator;
stack<long long int> Numerator;//分子
stack<long long int> Denominator;//分母
string result;
int PowModel = 0;//默认乘方为 ^
bool CheckQuestion(string Question) {
int i = 0;
while (Question[i] != '/' && Question[i] != '=') {
i++;
}
if (Question[i] == '=') {
return true;
}
if (Question[i] == '/') {
i++;
}
if (Question[i] >= '0' && Question[i] <= '9') {
return false;
}
else if (Question[i] == ' ') {
return true;
}
return false;
}
void ReadInt(string Question) {
for (int i = 0; Question[i] != '='; i++) {
//------------空格 + 左括号-----------
if (Question[i] == ' ') {
continue;
}
if (Question[i] == '(') {
Operator.push('(');
continue;
}
//---------------数字部分---------------
int number = 0;
if (Question[i] >= '0' && Question[i] <= '9') {
while (Question[i] >= '0' && Question[i] <= '9') {
number = number * 10 + Question[i] - '0';
i++;
}
i--;
Data.push(number);
continue;
}
//----------------运算符 + 计算----------------
if ((Question[i] < '0' || Question[i] > '9') && Question[i] != ' ') {
if (Question[i] == ')') {//当前运算符为右括号
while (Operator.top() != '(') {
Integer();
}
Operator.pop();
}
else if (Question[i] == '^') {//当前运算符为乘方,直接放入栈中即可
Operator.push(Question[i]);
}
else if(Question[i] != '^'){//如果当前运算符不为乘方
if (Question[i] == '(') {
Operator.push(Question[i]);
continue;
}
while (!Operator.empty() && Operator.top() == '^') {//先计算之前运算符里的乘方,从右到左
Integer();
}
if (!Operator.empty() &&( Operator.top() == '*' || Operator.top() == '/' ) ) {//当栈顶元素不为乘方后,乘除号优先
while (!Operator.empty() && (Operator.top() != '+' && Operator.top() != '-' && Operator.top()!='(')) {
Integer();
}
}
if (!Operator.empty() && (Question[i] == '+' || Question[i] == '-')) {//同一优先级自左向右算
while (!Operator.empty() && Operator.top() != '(') {
Integer();
}
}
Operator.push(Question[i]);
}
}
}
}
void ReadFraction(string Question) {
for (int i = 0; Question[i] != '='; i++) {
//---------------------括号处理-------------
if (Question[i] == '(') { //左括号直接入栈
Operator.push('(');
i++;//跳过之后的空格
continue;
}
if (Question[i] == ')') {//右括号不入栈,并会计算直到弹出距离栈顶最近的一个左括号
while (!Operator.empty() && Operator.top() != '(') {
Fraction();
}
Operator.pop();//弹出左括号
i++;//跳过之后空格
if (Question[i] == '=') {
return;
}
continue;
}
//--------------------分子分母计算---------------------
int number = 0;
int flag = 0;
while (Question[i] >= '0' && Question[i] <= '9') {
flag = 1;
number = number * 10 + Question[i] - '0';
i++;
}
if (flag != 0 && Question[i] == '/') {//后一位为 / 则为分子
Numerator.push(number);
continue;
}
else if (flag != 0 && Question[i] == ' ') {
Denominator.push(number);
continue;
}
//--------------------运算符入栈 + 计算-------------------------
if (Question[i] == ' ') {
char before = Question[i - 1];
if (Operator.empty() || Operator.top() == '(') {//如果栈为空,或者栈顶元素为左括号,那么此运算符入栈,然后跳过
Operator.push(before);
continue;
}
else {
if (!Operator.empty() && (before == '+' || before == '-')) {
while (!Operator.empty() && Operator.top() != '(') {//加减号之前的乘除加减都要先算
Fraction();
}
}
else if (!Operator.empty() &&(before == '*' || before == '/')) {//乘除号之前的乘除号要先算
if (!Operator.empty() && Operator.top() != '+' && Operator.top() != '-') {
Fraction();
}
}
Operator.push(before);
}
}
}
}
void Integer() {
char op = Operator.top();
long long int temp1 = Data.top();
Data.pop();
long long int temp2 = Data.top();
long long int ans = 0;
if (op == '+') {
ans = temp1 + temp2;
}
else if (op == '-') {
ans = temp2 - temp1;
}
else if (op == '*') {
ans = temp1 * temp2;
}
else if (op == '/') {
ans = temp2 / temp1;
}
else if (op == '^') {
ans = long long int(pow(temp2, temp1));
}
Data.top() = ans;
Operator.pop();
}
void CalInt() {
while (Data.size() > 1 && Operator.size() > 0) {
Integer();
}
result = Transform(int(Data.top()));
}
int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x%y);
}
int lcm(int x, int y) {
return x * y / gcd(x, y);
}
void Fraction() {
int numerator1 = 1;
numerator1 = int(Numerator.top());
Numerator.pop();
int numerator2 = 1;
numerator2 = int(Numerator.top());
Numerator.pop();
int numerator3 = 1;
int i = 0;
while (Question[i] != '/' && Question[i] != '=') {
i++;
}
if (Question[i] == '=') {
return true;
}
if (Question[i] == '/') {
i++;
}
if (Question[i] >= '0' && Question[i] <= '9') {
return false;
}
else if (Question[i] == ' ') {
return true;
}
return false;
}
void ReadInt(string Question) {
for (int i = 0; Question[i] != '='; i++) {
//------------空格 + 左括号-----------
if (Question[i] == ' ') {
continue;
}
if (Question[i] == '(') {
Operator.push('(');
continue;
}
//---------------数字部分---------------
int number = 0;
if (Question[i] >= '0' && Question[i] <= '9') {
while (Question[i] >= '0' && Question[i] <= '9') {
number = number * 10 + Question[i] - '0';
i++;
}
i--;
Data.push(number);
continue;
}
//----------------运算符 + 计算----------------
if ((Question[i] < '0' || Question[i] > '9') && Question[i] != ' ') {
if (Question[i] == ')') {//当前运算符为右括号
while (Operator.top() != '(') {
Integer();
}
Operator.pop();
}
else if (Question[i] == '^') {//当前运算符为乘方,直接放入栈中即可
Operator.push(Question[i]);
}
else if(Question[i] != '^'){//如果当前运算符不为乘方
if (Question[i] == '(') {
Operator.push(Question[i]);
continue;
}
while (!Operator.empty() && Operator.top() == '^') {//先计算之前运算符里的乘方,从右到左
Integer();
}
if (!Operator.empty() &&( Operator.top() == '*' || Operator.top() == '/' ) ) {//当栈顶元素不为乘方后,乘除号优先
while (!Operator.empty() && (Operator.top() != '+' && Operator.top() != '-' && Operator.top()!='(')) {
Integer();
}
}
if (!Operator.empty() && (Question[i] == '+' || Question[i] == '-')) {//同一优先级自左向右算
while (!Operator.empty() && Operator.top() != '(') {
Integer();
}
}
Operator.push(Question[i]);
}
}
}
}
void ReadFraction(string Question) {
for (int i = 0; Question[i] != '='; i++) {
//---------------------括号处理-------------
if (Question[i] == '(') { //左括号直接入栈
Operator.push('(');
i++;//跳过之后的空格
continue;
}
if (Question[i] == ')') {//右括号不入栈,并会计算直到弹出距离栈顶最近的一个左括号
while (!Operator.empty() && Operator.top() != '(') {
Fraction();
}
Operator.pop();//弹出左括号
i++;//跳过之后空格
if (Question[i] == '=') {
return;
}
continue;
}
//--------------------分子分母计算---------------------
int number = 0;
int flag = 0;
while (Question[i] >= '0' && Question[i] <= '9') {
flag = 1;
number = number * 10 + Question[i] - '0';
i++;
}
if (flag != 0 && Question[i] == '/') {//后一位为 / 则为分子
Numerator.push(number);
continue;
}
else if (flag != 0 && Question[i] == ' ') {
Denominator.push(number);
continue;
}
//--------------------运算符入栈 + 计算-------------------------
if (Question[i] == ' ') {
char before = Question[i - 1];
if (Operator.empty() || Operator.top() == '(') {//如果栈为空,或者栈顶元素为左括号,那么此运算符入栈,然后跳过
Operator.push(before);
continue;
}
else {
if (!Operator.empty() && (before == '+' || before == '-')) {
while (!Operator.empty() && Operator.top() != '(') {//加减号之前的乘除加减都要先算
Fraction();
}
}
else if (!Operator.empty() &&(before == '*' || before == '/')) {//乘除号之前的乘除号要先算
if (!Operator.empty() && Operator.top() != '+' && Operator.top() != '-') {
Fraction();
}
}
Operator.push(before);
}
}
}
}
void Integer() {
char op = Operator.top();
long long int temp1 = Data.top();
Data.pop();
long long int temp2 = Data.top();
long long int ans = 0;
if (op == '+') {
ans = temp1 + temp2;
}
else if (op == '-') {
ans = temp2 - temp1;
}
else if (op == '*') {
ans = temp1 * temp2;
}
else if (op == '/') {
ans = temp2 / temp1;
}
else if (op == '^') {
ans = long long int(pow(temp2, temp1));
}
Data.top() = ans;
Operator.pop();
}
void CalInt() {
while (Data.size() > 1 && Operator.size() > 0) {
Integer();
}
result = Transform(int(Data.top()));
}
int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x%y);
}
int lcm(int x, int y) {
return x * y / gcd(x, y);
}
void Fraction() {
int numerator1 = 1;
numerator1 = int(Numerator.top());
Numerator.pop();
int numerator2 = 1;
numerator2 = int(Numerator.top());
Numerator.pop();
int numerator3 = 1;
int denominator1 = 1;
denominator1 = int(Denominator.top());
Denominator.pop();
int denominator2 = 1;
denominator2 = int(Denominator.top());
Denominator.pop();
int denominator3 = 1;
denominator1 = int(Denominator.top());
Denominator.pop();
int denominator2 = 1;
denominator2 = int(Denominator.top());
Denominator.pop();
int denominator3 = 1;
char op = Operator.top();
//------------加减乘除-----------
if (op == '+' || op == '-') {
denominator3 = lcm(denominator1, denominator2);
numerator1 *= denominator3 / denominator1;
numerator2 *= denominator3 / denominator2;
if (op == '+') {
numerator3 = numerator2 + numerator1;
}
else {
numerator3 = numerator2 - numerator1;
}
}
else if (op == '*') {
numerator3 = numerator1 * numerator2;
denominator3 = denominator1 * denominator2;
}
else if (op == '/') {
numerator3 = numerator2 * denominator1;
denominator3 = denominator2 * numerator1;
}
//-------------若结果为负数---------
if (numerator3 * denominator3 < 0) {
numerator3 = numerator3 < 0 ? numerator3 : 0 - numerator3;
denominator3 = abs(denominator3);
}
//------------加减乘除-----------
if (op == '+' || op == '-') {
denominator3 = lcm(denominator1, denominator2);
numerator1 *= denominator3 / denominator1;
numerator2 *= denominator3 / denominator2;
if (op == '+') {
numerator3 = numerator2 + numerator1;
}
else {
numerator3 = numerator2 - numerator1;
}
}
else if (op == '*') {
numerator3 = numerator1 * numerator2;
denominator3 = denominator1 * denominator2;
}
else if (op == '/') {
numerator3 = numerator2 * denominator1;
denominator3 = denominator2 * numerator1;
}
//-------------若结果为负数---------
if (numerator3 * denominator3 < 0) {
numerator3 = numerator3 < 0 ? numerator3 : 0 - numerator3;
denominator3 = abs(denominator3);
}
Numerator.push(numerator3);
Denominator.push(denominator3);
Operator.pop();
}
void Simple() {
int gg = gcd(int(Numerator.top()), int(Denominator.top()));;
gg = abs(gg);
Numerator.top() /= gg;
Denominator.top() /= gg;
}
void CalFraction() {
while (!Operator.empty()) {
Fraction();
}
//---------特殊情况-------------
if (Numerator.top() == 0) {//分子为 0
result = "0";
return;
}
int temp = 0;
temp = int(Numerator.top() / Denominator.top());
Denominator.push(denominator3);
Operator.pop();
}
void Simple() {
int gg = gcd(int(Numerator.top()), int(Denominator.top()));;
gg = abs(gg);
Numerator.top() /= gg;
Denominator.top() /= gg;
}
void CalFraction() {
while (!Operator.empty()) {
Fraction();
}
//---------特殊情况-------------
if (Numerator.top() == 0) {//分子为 0
result = "0";
return;
}
int temp = 0;
temp = int(Numerator.top() / Denominator.top());
if (abs(temp) == 1 && (abs(Numerator.top()) - abs(Denominator.top()) == 0)) { //结果为 ±1
result = Transform(temp);
return;
}
result = Transform(temp);
return;
}
Numerator.top() = Numerator.top() % Denominator.top();
Simple();
//------------结果为真分数---------
result = Transform(int(Numerator.top())) + "/" + Transform(int(Denominator.top()));
//------------结果为假分数----------
if (abs(temp) > 0) {
result = Transform(temp) + "+" + result;
}
}
void Clear() {
while (!Data.empty()) {
Data.pop();
}
while (!Operator.empty()) {
Operator.pop();
}
while (!Numerator.empty()) {
Numerator.pop();
}
while (!Denominator.empty()) {
Denominator.pop();
}
}
string Transform(int data) {
string str;
int temp = 0;
if (data < 0) {
temp = 1;
}
data = abs(data);
if (data == 0) { //考虑为0的情况
return "0";
}
while (data != 0) {
char ch[2];
ch[0] = data % 10 + '0';
ch[1] = '\0';
str = ch + str;
data /= 10;
}
if (temp == 1) {
str = "-" + str;
}
return str;
}
string ToPower(string Question) {
string Power;
int i, j=0;
int len = Question.length();
for (i = 0,j = 0; i < len; i++) {
if (Question[i] != '*') {
Power[j] = Question[i];
j++;
continue;
}
else {
i++;
if (Question[i] != '*') {
Power[j] = Question[i - 1];
j++;
Power[j] = Question[i];
j++;
}
else {
Power[j] = '^';
j++;
}
}
}
return Power;
}
void Calculate(string Question) {
Clear();
if (PowModel) {
Question = ToPower(Question);
}
if (CheckQuestion(Question)) {
ReadInt(Question);
CalInt();
}
else {
ReadFraction(Question);
CalFraction();
}
}
void UserGUI(string user_answer) {
string answer;
int chance = 2;
answer = user_answer;
while (chance) {
if (answer == result) {
cout << "Rright!" << endl;
break;
}
else {
cout << "Wrong! You have " << chance << " chance to answer." << endl;
cin >> answer;
}
chance--;
}
if (!chance) {
cout << "So Sorry,This is right answer:" << result << endl;
}
cout << endl;
}
Simple();
//------------结果为真分数---------
result = Transform(int(Numerator.top())) + "/" + Transform(int(Denominator.top()));
//------------结果为假分数----------
if (abs(temp) > 0) {
result = Transform(temp) + "+" + result;
}
}
void Clear() {
while (!Data.empty()) {
Data.pop();
}
while (!Operator.empty()) {
Operator.pop();
}
while (!Numerator.empty()) {
Numerator.pop();
}
while (!Denominator.empty()) {
Denominator.pop();
}
}
string Transform(int data) {
string str;
int temp = 0;
if (data < 0) {
temp = 1;
}
data = abs(data);
if (data == 0) { //考虑为0的情况
return "0";
}
while (data != 0) {
char ch[2];
ch[0] = data % 10 + '0';
ch[1] = '\0';
str = ch + str;
data /= 10;
}
if (temp == 1) {
str = "-" + str;
}
return str;
}
string ToPower(string Question) {
string Power;
int i, j=0;
int len = Question.length();
for (i = 0,j = 0; i < len; i++) {
if (Question[i] != '*') {
Power[j] = Question[i];
j++;
continue;
}
else {
i++;
if (Question[i] != '*') {
Power[j] = Question[i - 1];
j++;
Power[j] = Question[i];
j++;
}
else {
Power[j] = '^';
j++;
}
}
}
return Power;
}
void Calculate(string Question) {
Clear();
if (PowModel) {
Question = ToPower(Question);
}
if (CheckQuestion(Question)) {
ReadInt(Question);
CalInt();
}
else {
ReadFraction(Question);
CalFraction();
}
}
void UserGUI(string user_answer) {
string answer;
int chance = 2;
answer = user_answer;
while (chance) {
if (answer == result) {
cout << "Rright!" << endl;
break;
}
else {
cout << "Wrong! You have " << chance << " chance to answer." << endl;
cin >> answer;
}
chance--;
}
if (!chance) {
cout << "So Sorry,This is right answer:" << result << endl;
}
cout << endl;
}
心得体会:
感受到了自己的代码知识在面对真正软件开发的不足,之前一直认为自己目前所学的知识,应该可以编写一些小型程序,但经过编写本次程序,才知道自己的代码知识差距了多少。写博客的训练,让自己总结出了自己的不足和代码思路的提炼。让自己找到了学习的方向。