结对变成项目总结

如下图,为我们做的判卷程序,左侧为出题区,中间为答题去,右侧为结果区

首先点击自动出题按钮,自动生成50道题目,长度随机

然后点击开始测试按钮,即进入如下界面,学生可在题目后方的输入框内答题

全部答完后,点击确认提交按钮,自动判卷

最终结果会显示在右边,例如每道题目的答案和对错数量的信息

之后点击再次测试按钮,可以继续答下10道题,总共有50道题,如果全部答完后,还想继续,可以再次点击自动出题按钮,然后可以继续测试

测试结束后,点击退出测试按钮即可退出程序。

以下为本程序的全部代码

  1 // MFCTest4Dlg.cpp : 实现文件
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "MFCTest4.h"
  6 #include "MFCTest4Dlg.h"
  7 #include "afxdialogex.h"
  8 #include "Calculator.h"
  9 #include <string>
 10 #include "Auto_Equation.h"
 11 
 12 #ifdef _DEBUG
 13 #define new DEBUG_NEW
 14 #endif
 15 
 16 //int EqNum;
 17 MyError temperror;                            //错误缓存
 18 string str_buf[10];                            //算式缓存
 19 int correct;                                //正确题数
 20 int incorrect;                                //错误题数
 21 CString answer[10];                            //结果存在这里
 22 Calculator cal("1+1");                        //创建计算器类
 23 bool last;                                    //是否是最后一组题
 24 ifstream in("equation.txt");                //打开算式所在文件
 25 
 26 
 27 // CMFCTest4Dlg 对话框
 28 
 29 
 30 
 31 CMFCTest4Dlg::CMFCTest4Dlg(CWnd* pParent /*=NULL*/)
 32     : CDialogEx(IDD_MFCTEST4_DIALOG, pParent)
 33 {
 34     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 35 }
 36 
 37 void CMFCTest4Dlg::DoDataExchange(CDataExchange* pDX)
 38 {
 39     CDialogEx::DoDataExchange(pDX);
 40     //DDX_Control(pDX, IDC_EQUALITY, Equality);
 41     DDX_Control(pDX, IDC_EQUALITY1, Equality1);
 42     DDX_Control(pDX, IDC_EQUALITY2, Equality2);
 43     DDX_Control(pDX, IDC_EQUALITY3, Equality3);
 44     DDX_Control(pDX, IDC_EQUALITY4, Equality4);
 45     DDX_Control(pDX, IDC_EQUALITY5, Equality5);
 46     DDX_Control(pDX, IDC_EQUALITY6, Equality6);
 47     DDX_Control(pDX, IDC_EQUALITY7, Equality7);
 48     DDX_Control(pDX, IDC_EQUALITY8, Equality8);
 49     DDX_Control(pDX, IDC_EQUALITY9, Equality9);
 50     DDX_Control(pDX, IDC_EQUALITY10, Equality10);
 51     DDX_Control(pDX, IDC_A1, Answer1);
 52     DDX_Control(pDX, IDC_A2, Answer2);
 53     DDX_Control(pDX, IDC_A3, Answer3);
 54     DDX_Control(pDX, IDC_A4, Answer4);
 55     DDX_Control(pDX, IDC_A5, Answer5);
 56     DDX_Control(pDX, IDC_A6, Answer6);
 57     DDX_Control(pDX, IDC_A7, Answer7);
 58     DDX_Control(pDX, IDC_A8, Answer8);
 59     DDX_Control(pDX, IDC_A9, Answer9);
 60     DDX_Control(pDX, IDC_A10, Answer10);
 61 }
 62 
 63 BEGIN_MESSAGE_MAP(CMFCTest4Dlg, CDialogEx)
 64     ON_WM_PAINT()
 65     ON_WM_QUERYDRAGICON()
 66     ON_BN_CLICKED(IDOK, &CMFCTest4Dlg::OnBnClickedOk)
 67     ON_EN_CHANGE(IDC_EDIT1, &CMFCTest4Dlg::OnEnChangeEdit1)
 68     //ON_STN_CLICKED(IDC_STATIC_INT, &CMFCTest4Dlg::OnStnClickedStaticInt)
 69     //ON_BN_CLICKED(IDC_BUTTON1, &CMFCTest4Dlg::OnBnClickedButton1)
 70     ON_STN_CLICKED(IDC_STATIC1, &CMFCTest4Dlg::OnStnClickedStatic1)
 71     ON_STN_CLICKED(IDC_EQUALITY2, &CMFCTest4Dlg::OnStnClickedEquality2)
 72     ON_BN_CLICKED(IDOK2, &CMFCTest4Dlg::OnBnClickedOk2)
 73     ON_BN_CLICKED(IDC_BUTTON10, &CMFCTest4Dlg::OnBnClickedButton10)
 74     ON_EN_CHANGE(IDC_EDIT2, &CMFCTest4Dlg::OnEnChangeEdit2)
 75     ON_BN_CLICKED(IDC_AUTO, &CMFCTest4Dlg::OnBnClickedAuto)
 76 END_MESSAGE_MAP()
 77 
 78 
 79 // CMFCTest4Dlg 消息处理程序
 80 
 81 BOOL CMFCTest4Dlg::OnInitDialog()
 82 {
 83     CDialogEx::OnInitDialog();
 84 
 85     // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
 86     //  执行此操作
 87     SetIcon(m_hIcon, TRUE);            // 设置大图标
 88     SetIcon(m_hIcon, FALSE);        // 设置小图标
 89 
 90     // TODO: 在此添加额外的初始化代码
 91     GetDlgItem(IDC_BUTTON10)->EnableWindow(false);
 92 
 93     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
 94 }
 95 
 96 // 如果向对话框添加最小化按钮,则需要下面的代码
 97 //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
 98 //  这将由框架自动完成。
 99 
100 void CMFCTest4Dlg::OnPaint()
101 {
102     if (IsIconic())
103     {
104         CPaintDC dc(this); // 用于绘制的设备上下文
105 
106         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
107 
108         // 使图标在工作区矩形中居中
109         int cxIcon = GetSystemMetrics(SM_CXICON);
110         int cyIcon = GetSystemMetrics(SM_CYICON);
111         CRect rect;
112         GetClientRect(&rect);
113         int x = (rect.Width() - cxIcon + 1) / 2;
114         int y = (rect.Height() - cyIcon + 1) / 2;
115 
116         // 绘制图标
117         dc.DrawIcon(x, y, m_hIcon);
118     }
119     else
120     {
121         CDialogEx::OnPaint();
122     }
123 }
124 
125 //当用户拖动最小化窗口时系统调用此函数取得光标
126 //显示。
127 HCURSOR CMFCTest4Dlg::OnQueryDragIcon()
128 {
129     return static_cast<HCURSOR>(m_hIcon);
130 }
131 
132 void CMFCTest4Dlg::OnBnClickedOk()                //这个是"开始测试"按钮
133 {
134     // TODO: 在此添加控件通知处理程序代码
135     CDialogEx::OnOK();
136 }
137 
138 void CMFCTest4Dlg::OnEnChangeEdit1()
139 {
140     // TODO:  如果该控件是 RICHEDIT 控件,它将不
141     // 发送此通知,除非重写 CDialogEx::OnInitDialog()
142     // 函数并调用 CRichEditCtrl().SetEventMask(),
143     // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
144 
145     // TODO:  在此添加控件通知处理程序代码
146     //SetDlgItemText(IDC_STATIC1, "shit");
147     /*CString str;
148     GetDlgItemText(IDC_EDIT1, str);
149     str.Format("算式%d", ++EqNum);
150     SetDlgItemText(IDC_STATIC1, str);*/
151 }
152 
153 
154 void CMFCTest4Dlg::OnStnClickedStaticInt()
155 {
156     // TODO: 在此添加控件通知处理程序代码
157 
158 }
159 
160 
161 void CMFCTest4Dlg::OnBnClickedButton1()//这个是“确定”按钮
162 {
163     // TODO: 在此添加控件通知处理程序代码
164     
165     
166     
167     //EqNum++;
168 }
169 
170 
171 void CMFCTest4Dlg::OnStnClickedStatic1()
172 {
173     // TODO: 在此添加控件通知处理程序代码
174 }
175 
176 
177 void CMFCTest4Dlg::OnStnClickedEquality2()
178 {
179     // TODO: 在此添加控件通知处理程序代码
180 }
181 
182 
183 void CMFCTest4Dlg::OnBnClickedOk2()        //真正的开始按钮
184 {
185     // TODO: 在此添加控件通知处理程序代码
186     int e = 0;
187     last = false;
188     correct = 0;
189     incorrect = 0;
190     SetDlgItemText(IDC_CORRECT, "0");
191     SetDlgItemText(IDC_INCORRECT, "0");
192     
193     while (e < 10)
194     {
195         if (in >> str_buf[e])
196         {
197             switch (e)
198             {
199             case 0:
200                 SetDlgItemText(IDC_EDIT1, "");
201                 SetDlgItemText(IDC_A1, "第一题答案");
202                 SetDlgItemText(IDC_EQUALITY1, str_buf[e].c_str());
203                 break;
204             case 1:
205                 SetDlgItemText(IDC_EDIT2, "");
206                 SetDlgItemText(IDC_A2, "第二题答案");
207                 SetDlgItemText(IDC_EQUALITY2, str_buf[e].c_str());
208                 break;
209             case 2:
210                 SetDlgItemText(IDC_EDIT3, "");
211                 SetDlgItemText(IDC_A3, "第三题答案");
212                 SetDlgItemText(IDC_EQUALITY3, str_buf[e].c_str());
213                 break;
214             case 3:
215                 SetDlgItemText(IDC_EDIT4, "");
216                 SetDlgItemText(IDC_A4, "第四题答案");
217                 SetDlgItemText(IDC_EQUALITY4, str_buf[e].c_str());
218                 break;
219             case 4:
220                 SetDlgItemText(IDC_EDIT5, "");
221                 SetDlgItemText(IDC_A5, "第五题答案");
222                 SetDlgItemText(IDC_EQUALITY5, str_buf[e].c_str());
223                 break;
224             case 5:
225                 SetDlgItemText(IDC_EDIT6, "");
226                 SetDlgItemText(IDC_A6, "第六题答案");
227                 SetDlgItemText(IDC_EQUALITY6, str_buf[e].c_str());
228                 break;
229             case 6:
230                 SetDlgItemText(IDC_EDIT7, "");
231                 SetDlgItemText(IDC_A7, "第七题答案");
232                 SetDlgItemText(IDC_EQUALITY7, str_buf[e].c_str());
233                 break;
234             case 7:
235                 SetDlgItemText(IDC_EDIT8, "");
236                 SetDlgItemText(IDC_A8, "第八题答案");
237                 SetDlgItemText(IDC_EQUALITY8, str_buf[e].c_str());
238                 break;
239             case 8:
240                 SetDlgItemText(IDC_EDIT9, "");
241                 SetDlgItemText(IDC_A9, "第九题答案");
242                 SetDlgItemText(IDC_EQUALITY9, str_buf[e].c_str());
243                 break;
244             case 9:
245                 SetDlgItemText(IDC_EDIT10, "");
246                 SetDlgItemText(IDC_A10, "第十题答案");
247                 SetDlgItemText(IDC_EQUALITY10, str_buf[e].c_str());
248                 break;
249             }
250         }
251         else
252         {
253             last = true;
254         }
255         e++;
256     }
257     //按完开始之后就不能再次按下
258     SetDlgItemText(IDOK2, "再次测试");
259     GetDlgItem(IDOK2)->EnableWindow(false);
260     GetDlgItem(IDC_BUTTON10)->EnableWindow(true);
261     if (last)
262     {
263         MessageBox("没有更多的题了!测试结束!", "提示", MB_ICONINFORMATION);
264         GetDlgItem(IDC_BUTTON10)->EnableWindow(false);
265         in.close();
266     }
267 }
268 
269 
270 void CMFCTest4Dlg::OnBnClickedButton10()//确认提交按钮
271 {
272     int a = 0;
273     //循环存用户答案
274     while (a < 10)
275     {
276         cal.recalculator(str_buf[a]);                    //重启计算器,并传入算式参数
277         temperror = cal.run();
278         switch (a)
279         {
280         case 0:
281             GetDlgItemText(IDC_EDIT1, answer[a]);
282             SetDlgItemText(IDC_A1, cal.getMyResult().c_str());
283             break;
284         case 1:
285             GetDlgItemText(IDC_EDIT2, answer[a]);
286             SetDlgItemText(IDC_A2, cal.getMyResult().c_str());
287             break;
288         case 2:
289             GetDlgItemText(IDC_EDIT3, answer[a]);
290             SetDlgItemText(IDC_A3, cal.getMyResult().c_str());
291             break;
292         case 3:
293             GetDlgItemText(IDC_EDIT4, answer[a]);
294             SetDlgItemText(IDC_A4, cal.getMyResult().c_str());
295             break;
296         case 4:
297             GetDlgItemText(IDC_EDIT5, answer[a]);
298             SetDlgItemText(IDC_A5, cal.getMyResult().c_str());
299             break;
300         case 5:
301             GetDlgItemText(IDC_EDIT6, answer[a]);
302             SetDlgItemText(IDC_A6, cal.getMyResult().c_str());
303             break;
304         case 6:
305             GetDlgItemText(IDC_EDIT7, answer[a]);
306             SetDlgItemText(IDC_A7, cal.getMyResult().c_str());
307             break;
308         case 7:
309             GetDlgItemText(IDC_EDIT8, answer[a]);
310             SetDlgItemText(IDC_A8, cal.getMyResult().c_str());
311             break;
312         case 8:
313             GetDlgItemText(IDC_EDIT9, answer[a]);
314             SetDlgItemText(IDC_A9, cal.getMyResult().c_str());
315             break;
316         case 9:
317             GetDlgItemText(IDC_EDIT10, answer[a]);
318             SetDlgItemText(IDC_A10,cal.getMyResult().c_str());
319             break;
320         }
321         if (answer[a].GetString() == cal.getMyResult())
322         {
323             correct++;
324         }
325         else
326         {
327             incorrect++;
328         }
329         a++;
330     }
331     if (temperror != ERROR_NO)                        //显示错误
332     {
333         MessageBox(printError(temperror).c_str(), "ERROR", MB_ICONHAND);
334     }
335     char buf[2][3];
336     sprintf(buf[0], "%d", correct);
337     sprintf(buf[1], "%d", incorrect);
338     SetDlgItemText(IDC_CORRECT, buf[0]);
339     SetDlgItemText(IDC_INCORRECT, buf[1]);
340     // TODO: 在此添加控件通知处理程序代码
341     GetDlgItem(IDOK2)->EnableWindow(true);
342     GetDlgItem(IDC_BUTTON10)->EnableWindow(false);
343 }
344 
345 
346 void CMFCTest4Dlg::OnEnChangeEdit2()
347 {
348     // TODO:  如果该控件是 RICHEDIT 控件,它将不
349     // 发送此通知,除非重写 CDialogEx::OnInitDialog()
350     // 函数并调用 CRichEditCtrl().SetEventMask(),
351     // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
352 
353     // TODO:  在此添加控件通知处理程序代码
354 
355 }
356 
357 
358 void CMFCTest4Dlg::OnBnClickedAuto()
359 {
360     // TODO: 在此添加控件通知处理程序代码
361     srand((int)time(0));
362     string equation;
363     char temp[100];
364     ofstream outf("equation.txt");
365     int i = 50;
366     //cout << "输入生成算式的数量:";
367     //cin >> i;
368     while (i--) {
369         equation.clear();
370         if (i % 2) {                                            //分数运算 
371             char lastop = '+';                                //上一个运算符 
372             int num = random(5) + 4;                            //算式包含的操作数个数-1 
373             sprintf(temp, "%d", random(20) + 1);                 //第一个操作数 
374             equation.append(temp);
375             while (num--) {
376                 int b;
377                 if (lastop == '/')                            //防止连续除法的出现 
378                     b = random(2);
379                 else
380                     b = random(12);
381                 switch (b) {
382                 case 0:
383                 case 4:
384                 case 8:
385                     lastop = temp[0] = '+';
386                     break;
387                 case 1:
388                 case 5:
389                 case 9:
390                     lastop = temp[0] = '-';
391                     break;
392                 case 2:
393                 case 6:
394                 case 10:
395                     lastop = temp[0] = '*';
396                     break;
397                 case 3:
398                 case 7:
399                 case 11:
400                     lastop = temp[0] = '/';
401                     break;
402                 }
403                 temp[1] = 0;
404                 equation.append(temp);
405                 sprintf(temp, "%d", random(20) + 1);
406                 equation.append(temp);
407             }
408             int k, a = 0;
409             for (int j = 0; j<equation.size(); j++) {                    //添加括号 
410                 if ((equation[j] == '+' || equation[j] == '-') && a == 0) {
411                     a++;
412                 }
413                 else if ((equation[j] == '+' || equation[j] == '-') && a == 1) {
414                     k = j - 1;                                            //添加左括号 
415                     while (!isoperator(equation[k - 1]) && k != 0) k--;
416                     if (equation[k - 1] == '/') {
417                         k--;
418                         while (!isoperator(equation[k - 1]) && k != 0) k--;
419                     }
420                     equation.insert(k, "(");
421 
422                     k = j + 2;                                            //添加右括号 
423                     while (!isoperator(equation[k + 1]) && k != equation.size() - 1) k++;
424                     equation.insert(k + 1, ")");
425 
426                     break;
427                 }
428             }
429             //cout<<equation<<endl;
430         }
431         else {                                                        //小数运算 
432             char lastop = '+';                                //上一个运算符 
433             int num = random(5) + 4;                            //算式包含的操作数个数-1 
434             int temp1 = random(200) + 1;
435             sprintf(temp, "%g", temp1 / 10.0);                 //第一个操作数 
436             equation.append(temp);
437             while (num--) {
438                 int b;
439                 if (lastop == '/')                            //防止连续除法的出现 
440                     b = random(2);
441                 else
442                     b = random(12);
443                 switch (b) {
444                 case 0:
445                 case 4:
446                 case 8:
447                     lastop = temp[0] = '+';
448                     break;
449                 case 1:
450                 case 5:
451                 case 9:
452                     lastop = temp[0] = '-';
453                     break;
454                 case 2:
455                 case 6:
456                 case 10:
457                     lastop = temp[0] = '*';
458                     break;
459                 case 3:
460                 case 7:
461                 case 11:
462                     lastop = temp[0] = '/';
463                     break;
464                 }
465                 temp[1] = 0;
466                 equation.append(temp);
467                 int temp2 = random(200) + 1;
468                 if (equation[equation.size() - 1] == '/' && (temp1%temp2) != 0) {
469                     temp2 = temp1 / 5 + 1;
470                     while (temp1%temp2) {
471                         temp2++;
472                     }
473                 }
474                 temp1 = temp2;
475                 sprintf(temp, "%g", temp2 / 10.0);
476                 equation.append(temp);
477             }
478             //cout<<equation<<endl;
479         }
480         outf << equation << endl;
481     }
482     //cout << "生成算式成功" << endl;
483     MessageBox("生成50道算式成功", "提示", MB_ICONINFORMATION);
484     GetDlgItem(IDOK2)->EnableWindow(true);
485     in.close();
486     in.open("equation.txt");
487     outf.close();
488 }
MFC code
  1 #pragma once
  2 #include <iostream>
  3 using namespace std;
  4 #include <string.h>
  5 #include <stack>
  6 #include <sstream>
  7 #include <fstream>
  8 #include <stdlib.h>
  9 #include <stdio.h>
 10 #include <math.h>
 11 
 12 enum MyError { ERROR_NO = 0, ERROR_SET = 1, ERROR_OPERATOR = 2, ERROR_ZERO = 4, ERROR_STRING = 8, ERROR_RANGE = 16 };
 13 
 14 string printError(MyError me) {
 15     if (me == ERROR_NO) {
 16         return "没有错误";
 17     }
 18     else if (me == ERROR_SET) {
 19         return "设置参数非法";
 20     }
 21     else if (me == ERROR_OPERATOR) {
 22         return "操作符非法";
 23     }
 24     else if (me == ERROR_ZERO) {
 25         return "除0错误";
 26     }
 27     else if (me == ERROR_STRING) {
 28         return "算式非法";
 29     }
 30     else if (me == ERROR_RANGE) {
 31         return "计算结果超出范围";
 32     }
 33     else {
 34         return "未定义的错误类型";
 35     }
 36     //cout<< "    错误代码:" << me << endl << endl;
 37 }
 38 
 39 class unit                        //后缀表达式用,单元类 
 40 {
 41 public:
 42     char op;
 43     double num;
 44     int kind;
 45     unit() {
 46         kind = 0;
 47     }
 48     void set(char c) {
 49         op = c;
 50         kind = 1;
 51     }
 52     void set(double d) {
 53         num = d;
 54         kind = 2;
 55     }
 56 };
 57 
 58 class fenshu                        //分数类 
 59 {
 60 public:
 61     int fz;
 62     int fm;
 63     fenshu(int a, int b) {
 64         fz = a; fm = b;
 65         yuefen();
 66     }
 67     void yuefen() {
 68         if (fz == 0)
 69             return;
 70         int t;
 71         int a = fz;
 72         int b = fm;
 73         if (a < b) {
 74             t = a;
 75             a = b;
 76             b = t;
 77         }
 78         while (t = a % b) {
 79             a = b;
 80             b = t;
 81         }
 82         if (b != 1) {
 83             fz /= b;
 84             fm /= b;
 85         }
 86         if (fm<0) {
 87             fz = -fz;
 88             fm = -fm;
 89         }
 90     }
 91     void print() {
 92         cout << fz << "/" << fm;
 93     }
 94     string getfenshu() {
 95         char s[20];
 96         if (fm == 1) {
 97             sprintf(s, "%d", fz);
 98         }
 99         else {
100             sprintf(s, "%d/%d", fz, fm);
101         }
102         string ss = s;
103         return ss;
104     }
105     fenshu operator +(fenshu &fs) {
106         fenshu f(fz*fs.fm + fs.fz*fm, fm*fs.fm);
107         f.yuefen();
108         return f;
109     }
110     fenshu operator -(fenshu &fs) {
111         fenshu f(fz*fs.fm - fs.fz*fm, fm*fs.fm);
112         f.yuefen();
113         return f;
114     }
115     fenshu operator *(fenshu &fs) {
116         fenshu f(fz*fs.fz, fs.fm*fm);
117         f.yuefen();
118         return f;
119     }
120     fenshu operator /(fenshu &fs) {
121         if (fs.fz == 0) {
122             fenshu f1(0, 1);
123             return f1;
124         }
125         fenshu f(fz*fs.fm, fm*fs.fz);
126         f.yuefen();
127         return f;
128     }
129     void operator =(fenshu &fs) {
130         fz = fs.fz;
131         fm = fs.fm;
132     }
133     bool operator ==(fenshu &fs) {
134         return fz == fs.fz&&fm == fs.fm;
135     }
136 };
137 
138 class Calculator                    //核心计算器类 
139 {
140 public:
141     //辅助计算参数 
142     double result;                    //计算结果 
143     fenshu fresult;                    //分数计算结果 
144     MyError Error;                    //计算过程中是否有错误 
145     string str;                        //存放中缀表达式 
146 
147     Calculator(string s) :fresult(1, 1) {            //计算器初始化 
148         u = new unit();
149         str = s;
150         accuracy = -1;
151         maxunit = 80;
152         daterange = 1000;
153         clear();
154     }
155 
156     MyError run() {                        //计算表达式的值,存入result
157         MyError temperror = zzh(str);
158         if (temperror != ERROR_NO) {
159             Error = temperror;
160             result = -11111;
161             return Error;
162         }
163         int i;
164         bool b = true;
165         for (i = 0; i<str.size(); i++) {    //没有小数点,就计算分数结果 
166             if (str[i] == '.') {
167                 b = false;
168                 break;
169             }
170 
171         }
172 
173         if (b) {
174             temperror = getFResult();
175             if (temperror != ERROR_NO) {
176                 fenshu f(-1, -1);
177                 fresult = f;
178                 Error = temperror;
179                 return Error;
180             }
181             else if (abs(fresult.fz)>daterange || abs(fresult.fm)>daterange) {
182                 Error = ERROR_RANGE;
183                 return Error;
184             }
185         }
186         else {
187             temperror = getResult();
188             if (temperror != ERROR_NO) {
189                 Error = temperror;
190                 result = -11111;
191                 return Error;
192             }
193             else if (abs(result)>daterange) {
194                 Error = ERROR_RANGE;
195                 return Error;
196             }
197         }
198         return ERROR_NO;
199     }
200 
201     void clear() {                    //清空计算器一切辅助计算参数 
202         num = 0;
203         Error = ERROR_NO;
204         result = 0;
205         fenshu f(1, 1);
206         fresult = f;
207         str = "";
208         delete u;
209         u = new unit[maxunit];
210     }
211 
212     void recalculator(string s) {    //重启计算器对象 
213         clear();
214         str = s;
215     }
216 
217     string getMyResult() {                                //获得计算结果,小数结果或者分数结果 
218         int i = 0;
219         char s[20];
220         string ss;
221         for (; i<str.size(); i++) {
222             if (str[i] == '.') {
223                 if (accuracy != -1)                            //判断精度并输出 
224                     sprintf(s, "%.*lf", accuracy, result);
225                 else
226                     sprintf(s, "%g", result);
227                 ss = s;
228                 return ss;
229             }
230         }
231         ss = fresult.getfenshu();
232         return ss;
233     }
234 
235     MyError setDateRange(int type) {                //设置数据范围 
236         if (0<type) {
237             daterange = type;
238             return ERROR_NO;
239         }
240         else
241             Error = ERROR_SET;
242         return ERROR_SET;
243     }
244 
245     MyError setMaxUnit(int num) {                //设置最大识别数量 
246         if (0<num&&num <= 80) {
247             maxunit = num;
248             u = new unit[maxunit];             //清空后缀表达式 
249             this->num = 0;
250             return ERROR_NO;
251         }
252         else
253             Error = ERROR_SET;
254         return ERROR_SET;
255     }
256 
257     MyError setAccuracy(int a) {                    //设置精度 
258         if (a >= -1 && a <= 6) {
259             accuracy = a;
260             return ERROR_NO;
261         }
262         else
263             Error = ERROR_SET;
264         return ERROR_SET;
265     }
266 
267 private:
268     //非辅助计算参数,设置后,除非重复设置,否则不会被clear之类的清除 
269     int daterange;                    //算式参数中数据的范围 
270     int maxunit;                    //算式参数最多能识别的字符数量 
271     int accuracy;                    //小数精确位数,-1为不精确,即去掉所有末尾的0,其他数字即小数点后保留的位数 
272 
273                                     //辅助计算参数 
274     unit *u;                        //存储后缀表达式 
275     int num;                        //后缀表达式unit数量 
276 
277     MyError zzh(string s) {                        //中缀表达式转后缀表达式
278         if (s.size()>maxunit) {
279             return ERROR_STRING;                //error,传入的算式长度超过设置的最大识别数量
280         }
281         char c;
282         char *temp1 = new char[maxunit];
283         double temp;
284         string stemp;
285         stack<char> st;
286         while (!s.empty()) {                    //如果字符串不为空则继续循环 
287             c = s[0];
288             if (isoperator(c)) {                //是操作符 
289                 s.erase(0, 1);                //从string中删除操作符  
290                 if (pushintostack(c, &st) == ERROR_OPERATOR)
291                     return ERROR_OPERATOR;
292             }
293             else if (isnum(c)) {                            //是数字 
294                 stringstream sst(s);
295                 sst >> temp;
296                 sprintf(temp1, "%g", temp);
297                 stemp = temp1;
298                 s.erase(0, stemp.size());    //从string中删除数字
299                 sst.clear();
300                 u[num++].set(temp);            //存储数字到栈中 
301             }
302             else {
303                 return ERROR_STRING;
304             }
305         }
306         if (pushintostack('#', &st) == ERROR_OPERATOR)
307             return ERROR_OPERATOR;
308         return ERROR_NO;
309     }
310 
311     bool isoperator(char c) {                //判断是否是操作符 
312         if (c == '+')
313             return true;
314         if (c == '-')
315             return true;
316         if (c == '*')
317             return true;
318         if (c == '/')
319             return true;
320         if (c == '(')
321             return true;
322         if (c == ')')
323             return true;
324         return false;
325     }
326 
327     bool isnum(char c) {
328         if (c >= '0'&&c <= '9')
329             return true;
330         return false;
331     }
332 
333     int youxian(char c1, char c2) {            //判断两操作符优先级 
334         if (c2 == '#')        //结束符 
335             return 0;
336         if (c2 == '(')
337             return 1;
338         if (c2 == ')')
339             if (c1 == '(')
340                 return 2;
341             else
342                 return 0;
343         if (c1 == '(')
344             if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/')
345                 return 1;
346         if (c1 == '*' || c1 == '/')
347             return 0;
348         if (c1 == '+' || c1 == '-')
349             if (c2 == '*' || c2 == '/')
350                 return 1;
351             else if (c2 == '+' || c2 == '-')
352                 return 0;
353         return -1;                            //非法运算符 
354     }
355 
356     MyError pushintostack(char c, stack<char> *st) {        //将操作符执行一系列入栈判断操作 
357         char a;
358         int y = 0;
359         while (!st->empty()) {
360             a = st->top();
361             y = youxian(a, c);
362             if (y == 0) {                //后来的操作符优先级小 
363                 st->pop();
364                 u[num++].set(a);
365             }
366             else if (y == 1) {            //后来的操作符优先级大 
367                 break;
368             }
369             else if (y == 2) {            //俩操作符是'('和')'
370                 st->pop();
371                 return ERROR_NO;
372             }
373             else
374                 return ERROR_OPERATOR;
375         }
376         st->push(c);
377         return ERROR_NO;
378     }
379 
380     void test() {                                    //输出后缀表达式,测试用(暂留) 
381         int i;
382         cout << num << endl;
383         for (i = 0; i<num; i++) {
384             if (u[i].kind == 1)
385                 cout << u[i].op << " ";
386             else if (u[i].kind == 2)
387                 cout << u[i].num << " ";
388         }
389     }
390 
391     MyError getResult() {                        //由run函数调用,获取小数结果,存入result中 
392         int i;
393         char op;
394         double num1, num2;
395         stack<double> st;
396         for (i = 0; i<num; i++) {                    //处理后缀表达式 
397             if (u[i].kind == 2) {                //如果是数字则入栈 
398                 st.push(u[i].num);
399             }
400             else if (u[i].kind == 1) {            //如果是操作符,则出栈两个数字 
401                 op = u[i].op;
402                 if (st.empty())
403                     return ERROR_STRING;    //算式非法
404                 num2 = st.top();
405                 st.pop();
406                 if (st.empty())
407                     return ERROR_STRING;    //算式非法
408                 num1 = st.top();
409                 st.pop();
410                 switch (op) {
411                 case '+':
412                     st.push(num1 + num2);
413                     break;
414                 case '-':
415                     st.push(num1 - num2);
416                     break;
417                 case '*':
418                     st.push(num1*num2);
419                     break;
420                 case '/':
421                     if (num2 == 0)
422                         return ERROR_ZERO;    //除0错误
423                     st.push(num1 / num2);
424                     break;
425                 }
426             }
427             else
428                 return ERROR_STRING;        //算式非法
429         }
430         result = st.top();
431         return ERROR_NO;
432     }
433 
434     MyError getFResult() {                        //由run函数调用,获取分数结果,存入fresult中 
435         int i;
436         char op;
437         fenshu f1(1, 1), f2(1, 1);
438         stack<fenshu> st;
439         for (i = 0; i<num; i++) {
440             if (u[i].kind == 2) {                //如果是数字则入栈 
441                 st.push(fenshu(u[i].num, 1));
442             }
443             else if (u[i].kind == 1) {            //如果是操作符,则出栈两个数字 
444                 op = u[i].op;
445                 if (st.empty())
446                     return ERROR_STRING;    //算式非法
447                 f2 = st.top();
448                 st.pop();
449                 if (st.empty())
450                     return ERROR_STRING;    //算式非法
451                 f1 = st.top();
452                 st.pop();
453                 switch (op) {
454                 case '+':
455                     st.push(f1 + f2);
456                     break;
457                 case '-':
458                     st.push(f1 - f2);
459                     break;
460                 case '*':
461                     st.push(f1*f2);
462                     break;
463                 case '/':
464                     if (f2.fz == 0)
465                         return ERROR_ZERO;    //除0错误 
466                     st.push(f1 / f2);
467                     break;
468                 }
469             }
470             else
471                 return ERROR_STRING;        //算式非法
472         }
473         fresult = st.top();
474         return ERROR_NO;
475     }
476 
477 };
Calculator code
 1 #include<time.h>
 2 #include<stdlib.h>
 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
 4 #define random(x) (rand()%x)
 5 
 6 bool isoperator(char c) {
 7     if (c == '+' || c == '-' || c == '*' || c == '/')
 8         return true;
 9     return false;
10 }
auto_equation.h code

 

posted @ 2016-04-09 12:00  13070035王辰成  阅读(316)  评论(0编辑  收藏  举报