软件工程第三次作业

作业地址:【https://edu.cnblogs.com/campus/nenu/2016CS/homework/2266

git仓库地址:https://git.coding.net/pipifan/f4.git

我的结对成员是:孔文玉 2016011913

  http://www.cnblogs.com/kongwy/p/9919850.html

一、解题思路:

  解决四则运算问题,其实主要就难在不同符号的运算,优先级不同。我就直接预处理出了所有符号包括括号的优先级,然后用栈模拟一下。

  对于题目要求的不同功能,造不同的数据,例如:

功能一:整数加减法的数据(若是出现除0情况,则重新造数据)

           for(int i = 0 ; i < 7 ; i++ ){
                if( (i % 2) == 0 ){
                    int num = rand() % 10;
                    int len = s.size();
                    while( len > 0 && num == 0 && s[len - 1] == '/' )
                        num = rand() % 10;
                    stringstream ss;
                    ss << num;
                    string tmp;
                    ss >> tmp;
                    s += tmp;
                }
                else{
                    int num = rand() % 4;
                    s += mp[num];
                }
            }

功能二和三:带括号的整数和小数的数据

        else if( flag >= 2 ){
            int cnt1 = 0 , cnt2 = 0;
            double x[4];
            int xx = 0;
            for(int i = 0 ; i < 7 ; i++ ){
                string tmp;
                if( (i % 2) == 0 ){
                    int num = rand() % 10;
                    if( (num % 3) == 0 && num > 0 ){
                        int num1 = rand() % 100;
                        double tmp_num = num1*1.0 / 10;
                        stringstream ss;
                        ss << tmp_num;
                        ss >> tmp;
                        x[xx++] = tmp_num;
                    }
                    else{
                        int len = s.size();
                        while( len > 0 && num == 0 && s[len - 1] == '/' )
                            num = rand() % 10;
                        stringstream ss;
                        ss << num;
                        ss >> tmp;
                        x[xx++] = num*1.0;
                    }
                    if( num < 3 && i < 6 && i > 0 ){
                        s += "(";
                        cnt1++;
                    }
                    s += tmp;
                    if( num > 6  && i > 0 && i < 6){
                        if( cnt1 > 0 )
                            cnt1--;
                        else
                            cnt2++;
                        s += ")";
                    }
                }
                else{
                    int num = rand() % 4;
                    s += mp[num];
                }
            }
            sort( x , x + 4 );
            pdd now = mk( x[0] , x[1] , x[2] , x[3] );
            if( sta.find(now) != sta.end() ){
                tmp++;
                continue;
            }
            sta.insert( now );
            string before , after;
            for(int i = 0 ; i < cnt2 ; i++ )
                before += "(";
            for(int i = 0 ; i < cnt1 ; i++ )
                after  += ")";
            s = before + s + after;
        }
        double ans = solve(s);
        if( st.count(ans) ){
            tmp++;
            continue;
        }
        st.insert(ans);
        if( flag == 3 ){
            s += "=";
            vnum.push_back( ans );
            v.push_back(s);
            maxx = max(  maxx , (int)s.size() );
            continue;
        }
        cout<<s<<"
?";
        double me;
        scanf("%lf",&me);
        if( fabs(me - ans) <= eps ){
            cnt++;
            puts("回答正确。");
        }
        else{
            cout<<"回答错误,正确答案是";
            print(ans);
        }

难点:我觉得造括号的地方比较难,因为我得保证括号位置的随机性,又得保证左右括号数匹配,我最后是通过先随机造括号,再在两边加括号使得左右括号数匹配。

结对编程的体会:两个人编程确实比一个人快且方便,当遇到一个问题不会处理的时候,不再是一个人在网上盲目搜索, 而是先和队友提出来,每个人说出自己的问题和想法,再讨论之后,总能的得到一些新的进展,比如这次括号的处理问题,我们两个人就是通过讨论得出了解法。

三项花费时间长的问题:

  一、正确答案的计算(栈的运用,不同优先级运算的模拟)

  二、功能二中括号的处理(在保证括号出现位置的随机性上,又保证了括号序列的正确性)

  三、功能三的去重(相同的题目只出现一次, 朴素的想法是我把一个式子通过结合律、交换律、分配率所能出现的所有式子插入到一个set里面,然后logn查重,但是这样有点麻烦,最终我们选择了,测试一个式子的四个数是否相同,将4个数从小到大sort一下,然后包装起来塞到set里面,每次查重只用查这四个数是不是一样就行了,因为即使这样的方式查重,相同的概率也是微乎其微,不会太影响算法的复杂度)

 

原文地址:https://www.cnblogs.com/pipifan/p/9918250.html