之前写的东西,看了看在草稿里面,如果有报错自行修改哦~
#include <bits/stdc++.h>
#include <windows.h>
#define random(x) rand()%(x)//生成随机数
using namespace std;
string s;//要输入的字符串,需要进行分割使用
string s_t;//测试字符串
int a[10];//随机项的数
int sum, ts, ans;
char signn[10];//随机符号
stack<int> s1;//存放数的栈
stack<char> s2;//存放符号
void in();//输入
int doit();//计算
void calc();//计算
void exam();//测试模式
void exam1();//考试模式
void work();
int level(char p)//符号优先级
{
if (p == '+' || p == '-') return 1;
if (p == '*' || p == '/') return 2;
if (p == '^') return 3;
return 0;
}
inline void print()
{
//下面是C++11的黑科技,好方便
cout << R"(
************************************
************************************
** **
** **
** **
** 欢迎使用高级计算器系统 **
** **
** **
** **
** **
** abc **
************************************
************************************
)";
}
inline int doit(string str)
{
str = '(' + str + ')';//把s两端添加括号,方便最后运算
int i = 0;//下标
char ch = '(';//首位的(
do
{
if (ch == '(')//如果符号是左括号,直接入栈即可
{
s2.push('(');
}
else if (ch == ')')
{
while (s2.top() != '(') calc();//计算括号里所有的
s2.pop();//弹出(
}
else if (ch >= '0' && ch <= '9' || ch == '-' && str[i - 1] == '(')//如果这是个数,或者是个负数
{
int x, y;//x代表数,y代表符号
if (ch == '-') x = 0, y = -1;
else x = ch - '0', y = 1;
char ch0 = str[++i];//ch的下一个符号是否是数字呢? 会不会出现不是多位数呢?
while ('0' <= ch0 && ch0 <= '9')//如果是数字,那么我们就把他转换成int型的整数啊
{
x = x * 10 + (ch0 - '0');//简单的数学知识
ch0 = str[++i];//等同于i = i + 1; ch0 = str[i];
}
x *= y;//正负
s1.push(x);//就找到一个数字了,把他入栈
i--;
}
else//是个符号
{
while (level(ch) <= level(s2.top()))//当前运算符不超过栈顶运算,先算栈顶运算
//举个例子, 1+2*3 乘法比加法优先级高,那么先算乘法
{
calc();
}
s2.push(ch);//直到当前运算符高于栈顶运算符再把运算符存栈
}
} while (ch = str[++i]);//这里挺巧的,读到空字符也就终止了
return s1.top();//栈顶就是答案咯
}
inline void in()
{
char sig;//控制函数结束
cout << "请输入需要计算的式子( 例如: 3+4+5 或者 3*(4+5) ):" << endl;
cin >> s;
cout << "答案为:" << doit(s) << endl;//栈顶就是答案咯
stack<int>().swap(s1);
stack<char>().swap(s2);
cout << "是否继续计算 Y or N:" << endl;
cin >> sig;
if (sig == 'Y' || sig == 'y')//如果继续进行运算
{
system("cls");
in();
}
else
{
system("cls");
work();
}
}
inline void calc()
{
int n, m;
n = s1.top();//栈是个倒序的,所以第二个操作数在栈顶
s1.pop();
m = s1.top();//第一个操作数
s1.pop();
char z = s2.top();//符号
s2.pop();
switch (z)
{
case '+':s1.push(m + n);break;
case '-':s1.push(m - n);break;
case '*':s1.push(m * n);break;
case '/':s1.push(m / n);break;
case '^':s1.push(pow(m, n));break;
default:
break;
}
return;
}
inline void exam()
{
int n = random(3) + 2;//随机项数
for (int i = 1; i <= n; i++)//生成随机项数
{
a[i] = (random(20) + 1);
}
for (int i = 1; i < n; i++)
{
int t = random(3);
if (t == 0)
{
signn[i] = '+';
}
else if (t == 1)
{
signn[i] = '-';
}
else if (t == 2)
{
signn[i] = '*';
}
else
{
signn[i] = '/';
}
}
s_t = "";//初始化一下,避免重复调用时出问题
for (int i = 1; i <= n; i++)
{
if (i < n)
{
s_t = s_t + to_string(a[i]);//字符串拼接
s_t = s_t + signn[i];//把符号也拼进去
}
else
{
s_t = s_t + to_string(a[i]);//最后一位数字
}
}
cout << s_t << "=" << endl;
cout << "请输入您的答案:";
cin >> sum;
if (sum == doit(s_t))
{
cout << "答案正确!" << endl;
ans++;
}
else
{
cout << "答案错误!" << endl;
cout << "正确答案为:" << doit(s_t) << endl;
}
cout << "---------------------------" << endl;
}
inline void exam1()
{
ans = 0;//初始化
system("cls");
cout << R"(
************************************
欢迎进入练习系统
************************************
)";
cout << "请输入您想做的题数:";
cin >> ts;
cout << "---------------------------" << endl;
int ts1 = ts;
while (ts1--)
{
exam();
}
double rat = ans / (1.0 * ts) * 100;
cout << endl;
cout << "本次测试共" << ts << "道题," << "做对" << ans << "道!" << endl;
cout << "正确率为" << rat << "%" << endl;
Sleep(6000);
system("cls");
work();
}
inline void work()
{
char c;
cout << "请输入你想要执行的操作(输入序号):" << endl;
cout << "1.计算器" << endl;
cout << "2.计算练习" << endl;
cout << "3.退出" << endl;
cout << endl;
cout << "请输入:";
cin >> c;
switch (c)
{
case '1':
in();
break;
case '2':
exam1();
break;
case '3':
return;
break;
default:
cout << "输入错误,请重新输入" << endl;
Sleep(1000);
system("cls");
work();
break;
}
}
int main()
{
srand((int)time(0));//随机数种子
print();
work();
return 0;
}