zoukankan      html  css  js  c++  java
  • 结对变成项目总结

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

    首先点击自动出题按钮,自动生成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
  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/chengyu404/p/5371290.html
Copyright © 2011-2022 走看看