1. 程式人生 > >實現線上答題,可判斷對錯並儲存結果

實現線上答題,可判斷對錯並儲存結果

#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<fstream>
#include<iomanip>
#include<cmath>
#define random(x) (rand()%x)
using namespace std;

void Output(int sf) //開啟TXT記錄題目
{
if (sf == 1)
{
ofstream outfile("formula.txt", ios::out);
if (!outfile)
{
cout << "Open error!!" << endl;
exit(1);
}
outfile << "----------------作業集----------------" << endl;
outfile.close();
}
}


int Istrue_input(int num01) //判斷輸入0,1是否符合標準
{
while (1)
{
if (num01 != 0 && num01 != 1)
{
cout << "輸入有誤,請重新輸入(請輸入0或1):" << endl;
cin >> num01;
}
else
break;
}
return num01;
}


int Creat_random(int r1, int r2) //生成一定範圍的隨機數
{
int r, shu;
r = r2 - r1;
shu = r1 + rand() % r;
return shu;
}


string Create_oper(int lai) //生成隨機運算子
{
srand((int)time(0));
string sign;
int Num_sym, Sign_num;
if (lai == 0)//加減
Num_sym = 2;
else if (lai == 1)//加減乘除
Num_sym = 4;
Sign_num = rand() % Num_sym;//生成隨機的數字代表運算子
switch (Sign_num)
{
case(0) : sign = '+'; break;
case(1) : sign = '-'; break;
case(2) : sign = '*'; break;
case(3) : sign = '/'; break;
}
return sign;
}

/*判斷整數正負並取相反數*/
int Opp_zf(int a)
{
if (a < 0)
a = -a;
return a;
}

/*把int型別轉換為string型別*/
string Int_str(int shu)
{
char zhuan[100];
string str,zuo="(",you=")";
str=itoa(shu, zhuan, 10);
if (shu < 0)
str = zuo + str + you;
return str;
}

/*生成一個(某範圍)真分數*/
void Creat_fen(int r1, int r2, string &fenshu, double &zhi)
{
int i, r = r2 - r1, up, down, s;
bool flag;
string xian = "/", fu = "-", zuo = "(", you = ")";
string zhuan1, zhuan2;
loop:do
{
flag = false;//不能定義全域性變數!!
up = r1 + rand() % r;
up = Opp_zf(up);
down = r1 + rand() % r;
down = Opp_zf(down);
} while ((up >= down) || (down == 0) || (up == 0));//分子≥分母 or 分母=0 or 分子=0 重新生成

for (i = 2; i <= up; i++)
{

if (up%i == 0 && down%i == 0)
{
flag = true;//有公約數
break;
}
}
if (flag == true)
{
goto loop;
}
else
{
zhi = (double)up / (double)down;
zhuan1 = Int_str(up);//up/down都是正數不會再加一層括號
zhuan2 = Int_str(down);
s = rand() % 2;
switch (s)
{
//正分數
case(0) :
fenshu = zuo + zhuan1 + xian + zhuan2 + you;
break;
//負分數
case(1) :
fenshu = zuo + fu + zhuan1 + xian + zhuan2 + you;
zhi = -zhi;
break;
}
}

}


void Have_kuohao(int r1, int r2, string &formula,double &zhi)
{
srand((int)time(0));
int op,op1, op2;
int yn, qh;
string symbol1,symbol2;
string zhuan,zhuan1, zhuan2;
string jia = "+", jian = "-", cheng = "*", chu = "/",zuo="(",you=")";

zhi = (double)Creat_random(r1, r2);
op1 = Creat_random(r1, r2);
op2 = Creat_random(r1, r2);
op = Creat_random(r1, r2);//假設op2做分母不能為0
while (1)
{
if (op == 0)
op = Creat_random(r1, r2);
else
break;
}
zhuan1 = Int_str(zhi);
zhuan2 = Int_str(op);
symbol1 = Create_oper(1);

if (symbol1 == "+")
{
zhi = (double)op1 + (double)op2;
formula = zhuan1 + jia + zhuan2;
yn = rand() % 2;
switch (yn)
{
//外面不加括號
case(0) : break;
//外面加括號
case(1) :
{
formula = zuo + formula + you;
qh = rand() % 2;
symbol2 = Create_oper(1);
switch (qh)
{
//加到前面
case(0) :
{
formula = symbol2 + formula;
op = Creat_random(r1, r2);
zhuan = Int_str(op);
if (symbol2 == "+")
{
zhi = (double)op + zhi;
formula = zhuan + jia + formula;
}
else if (symbol2 == "-")
{
zhi = (double)op - zhi;
formula = zhuan + jian + formula;
}
else if (symbol2 == "*")
{
zhi = (double)op * zhi;
formula = zhuan + cheng + formula;
}
else if (symbol2 == "/")
{
if (zhi == 0)//防止出現隨機生成的除號後面的值為0;
break;
else
{
zhi = (double)op / zhi;
formula = zhuan + chu + formula;
}
}
break;

}
//加到後面
case(1) :
{
formula = formula + symbol2;
op = Creat_random(r1, r2);//防止後面隨機產生除號,分母為0
while (1)
{
if (op == 0)
op = Creat_random(r1, r2);
else
break;
}
zhuan = Int_str(op);
if (symbol2 == "+")
{
zhi = zhi + (double)op;
formula = formula + jia + zhuan;
}
else if (symbol2 == "-")
{
zhi = zhi - (double)op;
formula = formula + jian + zhuan;
}
else if (symbol2 == "*")
{
zhi = zhi * (double)op;
formula = formula + cheng + zhuan;
}
else if (symbol2 == "/")
{
zhi = zhi / (double)op;
formula = formula + chu + zhuan;
}
break;
}

}
break;
}


}


}
else if (symbol1 == "-")
{
zhi = (double)op1 - (double)op2;
formula = zhuan1 + jian + zhuan2;
}
else if (symbol1 == "*")
{
zhi = (double)op1 * (double)op2;
formula = zhuan1 + cheng + zhuan2;
}
else if (symbol1 == "/")
{
zhi = (double)op1 / (double)op2;
formula = zhuan1 + chu + zhuan2;
}



}

/*含有真分數*/
void Have_fenshu(int LL, int r1, int r2, string &formula, double &zhi, int jj)
{
srand((int)time(0));
string F1, F2, symbol, zhuan;
double Z1, Z2;//值
int inter, type;
inter = Creat_random(r1, r2);//整數
zhuan = Int_str(inter);
Creat_fen(r1, r2, F1, Z1);//分數1
Creat_fen(r1, r2, F2, Z2);//分數2
symbol = Create_oper(LL);//符號
type = rand() % 3;//型別

if (jj == 0)//加減沒有負數
{
inter = Opp_zf(inter);
zhuan = Int_str(inter);
while (1)
{
if (Z1 <0)
Creat_fen(r1, r2, F1, Z1);
else
break;
}
while (1)
{
if (Z2 <0)
Creat_fen(r1, r2, F2, Z2);
else
break;
}
}

switch (type)
{
//op1分數
case(0) :
formula = F1 + symbol + zhuan;
if (symbol == "+")
zhi = Z1 + (double)inter;
else if (symbol == "-")
{
if (jj == 0)
break;
else
zhi = Z1 - (double)inter;
}
else if (symbol == "*")
zhi = Z1 * (double)inter;
else if (symbol == "/")
{
if (inter != 0)
break;
else
zhi = Z1 / (double)inter;
}
break;
//op2分數
case(1) :
formula = zhuan + symbol + F1;
if (symbol == "+")
zhi = (double)inter + Z1;
else if (symbol == "-")
zhi = (double)inter - Z1;
else if (symbol == "*")
zhi = (double)inter * Z1;
else if (symbol == "/")
{
if (Z1 != 0)
zhi = (double)inter / Z1;
else
break;
}
break;
//全分數
case(2) :
formula = F1 + symbol + F2;
if (symbol == "+")
zhi = Z1 + Z2;
else if (symbol == "-")
{
if ((jj == 0) && (Z1 < Z2))
break;
else
zhi = Z1 - Z2;
}
else if (symbol == "*")
zhi = Z1 * Z2;
else if (symbol == "/")
{
if (Z1 != 0)
zhi = Z1 / Z2;
else
break;
}
break;
}

}

/*不含有真分數*/
void Only_integer(int LL, int r1, int r2, string &formula, double &zhi,int jj,int cc)
{
srand((int)time(0));
int op1, op2;
string symbol,zhuan1,zhuan2;
op1 = Creat_random(r1, r2);//整數1
op2 = Creat_random(r1, r2);//整數2
symbol = Create_oper(LL);//符號

if (jj == 0)//加減不含負號
{
op1 = Opp_zf(op1);
op2 = Opp_zf(op2);
if ((symbol == "-") && (op1 < op2))
{
int temp;
temp = op1;
op1 = op2;
op2 = temp;
}
}

if ((cc == 0) && (symbol == "/"))//除法不含餘數(去除負號計算的情況)
{
while (1)
{
op1 = Opp_zf(op1);
op2 = Opp_zf(op2);
if (op1 % op2 != 0)//有餘數,重新生成
{
op1 = Creat_random(r1, r2);
op2 = Creat_random(r1, r2);
}
else
break;
}
}

zhuan1 = Int_str(op1);
zhuan2 = Int_str(op2);
formula = zhuan1 + symbol + zhuan2;
if (symbol == "+")
zhi = op1 + op2;
else if (symbol == "-")
zhi = op1 - op2;
else if (symbol == "*")
zhi = op1*op2;
else if (symbol == "/")
zhi = op1 / op2;
}

void main()
{
ofstream outfile("formula.txt", ios::out);
if (!outfile)
{
cout << "open error!" << endl;
exit(1);
}
outfile << "----------------歡迎!小學生四則運算答題系統:-D----------------" << endl;

int i,j,N, R1, R2;
int SF, KH, FS, Lei,JJ,CC,count=0;
string question="";//生成的問題
double Zhi, answer;
int fenzi, fenmu;
bool repeat = false;

cout << "----------------歡迎!小學生四則運算答題系統:-D----------------"<<endl;
/*選擇題目範圍和數量*/
cout << "您想為孩子定製什麼範圍的題目呢?(可含有負數 && 上限≥下限):" << endl;
cout << "下限:";
cin >> R1;
cout << "上限:";
cin >> R2;
while (1)//是否輸入合法
{
if (R2 < R1)
{
cout << "輸入的範圍不合理,請重新輸入(上限≥下限):" << endl;
cout << "下限:";
cin >> R1;
cout << "上限:";
cin >> R2;
}
else
break;
}

cout << "訂製多少道題呢?請輸入個數:" << endl;
cout << "(友情提示:您不要為孩子出太多的題目(最多1000道)!謝謝合作!)" << endl;
cin >> N;
while (1)//是否輸入合法
{
if (N<=0||N>1000)
{
cout << "輸入的題目數量不合理,請重新輸入:" << endl;
cin >> N;
}
else
break;
}

/*選擇列印方式*/
cout << "您是否需要儲存文件?(0、不需要 1、需要)" << endl;
cin >> SF;
SF=Istrue_input(SF);//是否輸入合法
Output(SF);

cout << "*********下面請按照孩子的學習程度選擇題目的難度!!*********"<<endl;
/*是否含有括號*/
cout << "是否練習帶有括號的難度運算?(0、不需要 1、需要)";
cin >> KH;
KH=Istrue_input(KH);//是否輸入合法
if (KH == 1)//含括號
{
for (i = 1; i <= N; i++)
{
string Formula = "";
double Zhi;
Have_kuohao(R1, R2,Formula,Zhi);
}

}

//不含括號
else if (KH == 0)
{
/*加減運算或者四則運算*/
cout << "請選擇:0、只進行加減運算? 1、進行四則運算?";
cin >> Lei;
Lei=Istrue_input(Lei);//是否輸入合法

cout << "加減運算中是否有負數?(0、沒有 1、有)";
cin >> JJ;
JJ = Istrue_input(JJ);

if (Lei == 1)//乘除
{
cout << "除法中是否出現餘數?(0、沒有 1、有)";
cin >> CC;
CC = Istrue_input(CC);
}

/*是否含有真分數*/
cout << "題目中是否含有真分數?(0、不需要 1、需要)";
cin >> FS;
Istrue_input(FS);//是否輸入合法

cout << N << "道題目如下:" << endl;
if (SF == 1)//檔案輸出
{
outfile << N << "道題目如下:" << endl;
}
string ku[10000] ;

for (i = 1; i <= N; i++)
{
if (FS == 0)//全整數
Only_integer(Lei, R1, R2, question, Zhi, JJ, CC);
else if (FS == 1)//含真分數
Have_fenshu(Lei, R1, R2, question, Zhi, JJ);

ku[i] = question;
for (j = 0; j <i; j++)
{
if (ku[j] == ku[i])
{
i = i - 1;
repeat = true;//重複
break;
}
}
if (!repeat)//不重複
{
/*Is_rept(i,str);*/
cout << i << "、 " << question << " = " << endl;
if (SF == 1)//檔案輸出
{
outfile << i << "、 " << question << " = " << Zhi << endl;
}

if ((Zhi - (int)Zhi)< 1E-7 && (Zhi - (int)Zhi)> -(1E-7))//可認為它是整數
{
cin >> answer;
}
else
{
cout << " 分子:";
cin >> fenzi;
cout << " 分母:";
cin >> fenmu;
answer = (double)fenzi / (double)fenmu;
}

if ((answer - Zhi) < 1E-7 && (answer - Zhi) > -(1E-7))
{
cout << " √" << endl;
count++;
}
else
{
cout << " ×" << endl;
cout << "答案是:" << Zhi << endl;
}
}
}

cout << "您的孩子一共答對了" << count << "道題目!! 恭喜!!" << endl;
if (SF == 1)//檔案輸出
{
outfile << "您的孩子一共答對了" << count << "道題目!! 恭喜!!" << endl;
}
cout << "答錯的" << N - count << "道題目請分析原因並改正~~ 加油!!" << endl;
if (SF == 1)//檔案輸出
{
outfile << "答錯的" << N - count << "道題目請分析原因並改正~~ 加油!!" << endl;
}
}
outfile.close();

}

在上一次基礎上,增加了直接判斷正誤和儲存結果的功能,並可以根據自己的要求進行選擇。