自动出题软件--小结及初识界面设计

本文详细介绍了如何将中缀表达式转换为后缀表达式,并利用栈实现表达式的计算。此外,还介绍了使用Visual Studio中的MFC进行基本界面设计的方法。

总结及界面设计

git链接:
Operation3.1.1
这次修改内容:改变了语言的读取方式,把代码从dev移植到vs中。

关于栈的算法

       表达式的话我也没用到栈的知识,因为只是用到随机数随机符号,然后排列好了,也就没有检验的必要了。
       核心是在计算的时候。中缀表达式转后缀表达式,然后进行计算的道理都懂的,我就讲讲具体实现。假设自述表达式中的符号以字符形式由键盘输入,并存放在字符型数组str中,其后缀表达式存放在字符型数组exp中,在将自述表达式转换成后缀表达式的过程中用一个字符型数组stack作为栈。设字符“#”为表达式的终止符。下面给出将自述表达式转换成后缀表达式的方法。
       依次从键盘输入表达式中的字符ch,对于每一个ch做如下操作:

  1. 若ch为数字,将后续的所有数字依次存入数组exp中,并以字符“#”标示数字结束。
  2. 若ch为左括号“(”,则将此括号插入栈stack。
  3. 若ch为右括号“)”,则将栈stack中左括号“(”以前的字符依次删除并存入数组exp中,然后将左括号“(”删除。
  4. 若ch为“+”或“-”,则将当前栈stack中的栈顶端连续的“*”或“/”删除并依次存入数组exp中,然后将ch插入栈stack中。
  5. 若ch为“*”或“”,则将当前栈stack中的栈顶端连续的“*”或“/”删除并依次存入数组exp中,然后将ch插入栈stack中。
  6. 若ch为“#”,则将栈stack中的所有运算符依次删除并存入数组exp中,然后再将ch存入数组exp中。最后可在数组exp中得到表达式的后缀表示。

       对于表达式“(56-20)/(4+2)#”,其转换成后缀表达式的过程,就如下:

Stackexp说明
Ch为“(”,将此括号插入栈stack
56#Ch为数字,将56存入数组exp中,并插入一个字符“#”
(-56#Ch为“-”,由于stack中“(”以前没有字符,故直接将ch插入栈stack中
(-56#20#Ch为数字,将20#存入数组exp中
56#20#-Ch为“)”,将栈stack中“(”以前的字符依次删除并存入数组exp中,然后将“(”删除
56#20#-Ch为“/”,将ch插入栈stack中
/(56#20#-Ch为“(”,将此括号插入栈stack中
/(56#20#-4#Ch为数字,将4#存入数组exp中
/(+56#20#-4#Ch为“+”,由于stack中“(”以前没有字符,故直接将ch插入栈stack中
/(+56#20#-4#2#Ch为数字,将2#存入数组exp中
56#20#-4#2#+Ch为“)”,故将栈stack中“(”以前的字符依次删除并存入数组exp中,然后将“(”删除
56#20#-4#2#+/Ch为“#”,故将栈stack中的所有有符依次弹出并存入数组exp中,然后再将ch存入数组exp中,得到后缀表达式
int Question::check(string str)//用于计算生成的运算式的结果

{
    stringstream s;
    s << str << '#';
    str = s.str();
    s.str("");
    int   i, t, top = 0,len=str.length();
    double d;
    char str1[11]; //表达式
    char exp[15];  //存后缀表达式
    char stack[15]; //作为栈来使用
    char ch;
    for (i = 1; i <= len; i++)
        str1[i] = str[i - 1];
    
    t = 1; i = 1;
    ch = str1[i]; i++;
    while (ch != '#')
    {
        switch (ch)
        {
        case '(':  //判定为左括号
            top++; stack[top] = ch;
            break;
        case ')':  /*判定为右括号*/
            while (stack[top] != '(')
            {
                exp[t] = stack[top]; top--; t++;
            }
            top--;
            break;
        case '+':   /*判定为加减号*/
        case '-':
            while (top != 0 && stack[top] != '(')
            {
                exp[t] = stack[top]; top--; t++;
            }
            top++; stack[top] = ch;
            break;
        case '*':  /*判定为'*'或'/'号*/
        case '/':
            while (stack[top] == '*' || stack[top] == '/')
            {
                exp[t] = stack[top]; top--; t++;
            }
            top++; stack[top] = ch;
            break;
        case ' ':break;
        default:
            while (ch >= '0' && ch <= '9') /*判定为数字*/
            {
                exp[t] = ch; t++;
                ch = str1[i]; i++;
            }
            i--;
            exp[t] = '#'; t++;
        }
        ch = str1[i]; i++;
    }
    while (top != 0)
    {
        exp[t] = stack[top]; t++; top--;
    }
    exp[t] = '#';

    t = 1; top = 0;
    ch = exp[t]; t++;
    while (ch != '#')
    {
        switch (ch)
        {
        case '+':stack[top - 1] = stack[top - 1] + stack[top];
            top--; break;
        case '-':stack[top - 1] = stack[top - 1] - stack[top];
            top--; break;
        case '*':stack[top - 1] = stack[top - 1] * stack[top];
            top--; break;
        case '/':if (stack[top] != 0)
            stack[top - 1] = stack[top - 1] / stack[top];
                 else
                 {
                     printf("\n\t除零错误!\n");
                     exit(0);/*异常退出*/
                 }
                 top--; break;
        default:d = 0;
            while (ch >= '0' && ch <= '9')   /*判定为数字字符*/
            {
                d = 10 * d + ch - '0';  /*将数字字符转换成对应的数值*/
                ch = exp[t]; t++;
            }
            top++;
            stack[top] = char(d);
        }
        ch = exp[t]; t++;
    }
    return stack[top];
}

C++界面编程

本来是想看看Qt的,qt的方法学起来也很简单容易看懂跟swing有点相似,但是qt for vs2017的版本还没发布,只好用一下vs自带的MFC,MFC呢看起来比较繁琐
但是,如果不想自己敲代码,可以在创建MFC工程的时候选基于对话框,这样用起来就比较方便,跟vb一样的把控件拖入,设置控件的属性以及动作。不过MFC还要设置类、
变量等。
1092374-20170530163739696-1048902773.png
1092374-20170530163748196-1820291962.png
1092374-20170530163758414-2093342243.png

转载于:https://www.cnblogs.com/yyf031602438/p/6920721.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值