正文

我学c++Builder系列(7)2008-05-25 15:14:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/goal00001111/35439.html

分享到:

10,由系统给出正确答案

算法思路:当你希望获取更多的解或者更快的得到答案的话,就可以使用这个功能。我采用穷举的方法,让计算机列出参与运算的数字和符号的各种排列方式,并按照基本运算原则进行计算,最后详细分析了出现括号的各种情况,并以规定的格式进行输出。

新建一个Unit文件“UnitAnswer”,打开UnitAnswer.h,加入如下代码:

//---------------------------------------------------------------------------

#ifndef UnitAnswerH

#define UnitAnswerH

 

#include <vcl.h>

 

//穷举法列出参与运算的数字的各种排列方式

void CunShuZi(int num[]);

 

//回溯法输出各个可能的正确答案

void CunFuHao(int xuhao);

 

//根据序号返回对应的运算符

char FuHao(int i);

 

//计算当前四则运算表达式,并返回计算结果

int JiSuan(void);

 

//记录正确答案到文本文件中

void Print(int n);

//---------------------------------------------------------------------------

#endif

       然后切换到UnitAnswer.cpp,实现上述自定义函数。

//---------------------------------------------------------------------------

#pragma hdrstop

 

#include "UnitAnswer.h"

//---------------------------------------------------------------------------

 

#pragma package(smart_init)

 

const int MAX = 4; //参与运算的数字和符号的数量

int shuZi[MAX];    //存储参与运算的数字

char suanFu[MAX];  //存储可能的运算符,共4个:+,-,*,/

int iFile;           //文件句柄

String str("");    //用来存储各个正确答案

 

//---------------------------------------------------------------------------

//穷举法列出参与运算的数字的各种排列方式

void CunShuZi(int num[])

{

    DeleteFile("answer.txt");  //销毁原来的文本文件,以便记录本题的正确答案

    iFile = FileOpen("answer.txt", fmOpenReadWrite);

    if (iFile == -1)        //新建文件

           iFile = FileCreate("answer.txt", fmOpenReadWrite);

 

    int i, j, k;

     for (i=0; i<MAX; i++)//穷举法列出参与运算数字的各种排列方式

     {

           shuZi[0] = num[i];

          for (j=0; j<MAX; j++)

        {

                 if (i != j)

              {

                    shuZi[1] = num[j];

                     for (k=0; k<MAX; k++)

                     {

                       if (i != k && j != k)

                          {

                              shuZi[2] = num[k];

                                shuZi[3] = num[6-i-j-k];

                             CunFuHao(0);//存储运算符

                    }

                }

            }

        }

       }

    //输出最后一个答案到对话框,若无解则对话框的内容为空白

    MessageBox(NULL, str.c_str(), "答案", MB_OK);

    //MessageBox(NULL, "无解", "答案", MB_OK);

    FileClose(iFile);

}

//---------------------------------------------------------------------------

//回溯法输出各个可能的正确答案

void CunFuHao(int xuhao)

{

       int i;

  

     for (i=0; i<=3; i++)

     {

          suanFu[xuhao] = FuHao(i);

          if (xuhao < 2)

          {

               CunFuHao(xuhao+1);

        }

          else

          {

                 Print(JiSuan()); //记录当前正确答案

        }

     }

}

//---------------------------------------------------------------------------

//根据序号返回对应的运算符

char FuHao(int i)

{

     switch(i)

     {

          case 0: return '+';

          case 1: return '-';

          case 2: return '*';

          case 3: return '/';

     }

}

//---------------------------------------------------------------------------

//计算当前四则运算表达式,并返回计算结果

int JiSuan(void)

{

     int i;

     int result, sum1, sum2;

     int flag0, flag1, flag2;

 

    //判断第一,二,三个运算符是否为乘除运算符

     flag0 = (suanFu[0] == '*' || suanFu[0] == '/');

     flag1 = (suanFu[1] == '*' || suanFu[1] == '/');

     flag2 = (suanFu[2] == '*' || suanFu[2] == '/');

 

     if (!flag0 && flag1 && !flag2)//型如(a+b)*(c+d)

      {

          if (suanFu[0] == '+')

                    sum1 = shuZi[0] + shuZi[1];

          else

                 sum1 = shuZi[0] - shuZi[1];

         

           if (suanFu[2] == '+')

                    sum2 = shuZi[2] + shuZi[3];

          else

                 sum2 = shuZi[2] - shuZi[3];

         

        if (suanFu[1] == '*')

                    result = sum1 * sum2;

          else if (sum2 != 0 && sum1%sum2 == 0 )

                 result = sum1 / sum2; /*前后两个数必须能整除,且分母不为0*/

            else                       /*否则返回值12345(表示无效)*/

                   result = 12345;

     }

     if (result == 24) //得到型如(a+b)*(c+d)的答案

        return 1;

      

       if (suanFu[0] == '*' && suanFu[1] == '/' && !flag2)//型如a*b/(c+d)

      {

        result = shuZi[0] * shuZi[1];

       

          if (suanFu[2] == '+')

                    sum1 = shuZi[2] + shuZi[3];

          else

                 sum1 = shuZi[2] - shuZi[3];

         

           if (sum1 != 0 && result%sum1 == 0 )

                 result /= sum1; /*前后两个数必须能整除,且分母不为0*/

        else                       /*否则返回值12345(表示无效)*/

                   result = 12345;

     }

     if (result == 24)//得到型如a*b/(c+d)的答案

        return 2;

        

     if (suanFu[0] == '/' && !flag1 && !flag2)//型如a/(b+c)+d

      {

          if (suanFu[1] == '+')

                    sum1 = shuZi[1] + shuZi[2];

          else

                 sum1 = shuZi[1] - shuZi[2];

         

           if (sum1 != 0 && shuZi[0]%sum1 == 0 )

                 result = shuZi[0] / sum1; /*前后两个数必须能整除,且分母不为0*/

        else                   

                   goto A;

 

       if (suanFu[2] == '+')

          result += shuZi[3];

       else if (suanFu[2] == '-')

          result -= shuZi[3];

     }

A:

     if (result == 24) //得到型如a/(b+c)+d的答案

        return 3;

        

       if (flag0 && !flag1 && flag2)//型如a*b+c*d

      {

        if (suanFu[0] == '*')

                    sum1 = shuZi[0] * shuZi[1];

          else if (shuZi[1] != 0 && shuZi[0]%shuZi[1] == 0 )

                 sum1 = shuZi[0] / shuZi[1]; /*前后两个数必须能整除,且分母不为0*/

            else

                   goto B;

 

           if (suanFu[2] == '*')

                    sum2 = shuZi[2] * shuZi[3];

          else if (shuZi[3] != 0 && shuZi[2]%shuZi[3] == 0 )

                 sum2 = shuZi[2] / shuZi[3]; /*前后两个数必须能整除,且分母不为0*/

            else

                   goto B;

                  

             if (suanFu[1] == '+')

              result = sum1 + sum2;

         else

             result = sum1 - sum2;

     }

B:

       if (result == 24) //得到型如a*b+c*d的答案

        return 4;  

 

     result = shuZi[0];

     for (i=0; i<=2; i++)//其他形式

     {

         switch(suanFu[i])

         {

                   case '+':  result += shuZi[i+1]; break;

                   case '-':  result -= shuZi[i+1]; break;

                   case '*':  result *= shuZi[i+1]; break;

                   case '/':  if (shuZi[i+1] != 0 && result%shuZi[i+1] == 0 )

                                                  result /= shuZi[i+1]; /*前后两个数必须能整除,且分母不为0*/

                                 else                       /*否则返回值12345(表示无效)*/

                                              result = 12345;

                           break;

        }

    }

     if (result == 24) //得到其他形式的答案

        return 5;

  

   return 0;   //无解

}

//---------------------------------------------------------------------------

//记录正确答案到文本文件中

void Print(int n)

{

    if (n == 0)  //无解则不记录,直接返回到CunFuHao函数

       return;

      

    str = "     ";

     int flag0, flag1, flag2;

 

    //判断第一,二,三个运算符是否为乘除运算符

     flag0 = (suanFu[0] == '*' || suanFu[0] == '/');

     flag1 = (suanFu[1] == '*' || suanFu[1] == '/');

     flag2 = (suanFu[2] == '*' || suanFu[2] == '/');

  

     if     (n == 1)     //型如(a+b)*(c+d)

     {

           str += "(";

        str += shuZi[0];

        str += suanFu[0];

        str += shuZi[1];

        str += ")";

        str += suanFu[1];

        str += "(";

        str += shuZi[2];

        str += suanFu[2];

        str += shuZi[3];

        str += ")";

     }

     else if      (n == 2)    //型如a*b/(c+d)

     {

        str += shuZi[0];

        str += "*";

        str += shuZi[1];

        str += "/";

        str += "(";

        str += shuZi[2];

        str += suanFu[2];

        str += shuZi[3];

        str += ")";

     }

     else if      (n == 3)      //型如a/(b+c)+d

     {

        str += shuZi[0];

        str += "/";

        str += "(";

        str += shuZi[1];

        str += suanFu[1];

        str += shuZi[2];

        str += ")";

        str += suanFu[2];

        str += shuZi[3];

       

     }

     else if (n==5 && !flag0 && flag1) //型如(a+b)*c+d

     {

          str += "(";

        str += shuZi[0];

        str += suanFu[0];

        str += shuZi[1];

        str += ")";

        str += suanFu[1];

        str += shuZi[2];

        str += suanFu[2];

        str += shuZi[3];

     }

     else if (n==5 && !flag1 && flag2)//型如(a+b+c)*d

     {

          str += "(";

        str += shuZi[0];

        str += suanFu[0];

        str += shuZi[1];

        str += suanFu[1];

        str += shuZi[2];

        str += ")";

        str += suanFu[2];

        str += shuZi[3];

     }

    else  //不带括号的情况

     {

           for (int i=0; i<=2; i++)

          {

               str += shuZi[i];

               str += suanFu[i];

          }

        str += shuZi[3];

     }

    FileWrite(iFile, str.c_str(), str.Length());//记录正确答案

    //MessageBox(NULL, str.c_str(), "答案", MB_OK);

}

 

结语:

       至此,实现了我想要的功能。

       为了让您更好的参看这个程序,我给出UnitMain.h的内容。

//---------------------------------------------------------------------------

#ifndef UnitMainH

#define UnitMainH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <jpeg.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published:    // IDE-managed Components

       TButton *Button1;

       TButton *Button2;

       TEdit *Edit1;

       TImage *Image1;

       TImage *Image2;

       TImage *Image3;

       TImage *Image4;

       TLabel *Label5;

       TTimer *Timer1;

       void __fastcall Button1Click(TObject *Sender);

       void __fastcall Button2Click(TObject *Sender);

       void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);

       void __fastcall Timer1Timer(TObject *Sender);

       void __fastcall Edit1KeyPress(TObject *Sender, char &Key);

       void __fastcall Edit1KeyDown(TObject *Sender, WORD &Key,

          TShiftState Shift);

private:    // User declarations

       int ColorData[4];

    int SpendTime;

    bool IsInputValide();

       bool RightBracket(const String & str);

public:            // User declarations

       __fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

             

                                                                                                  goal000011112008-05-25

(全文完)

阅读(2712) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册