24点游戏 程序(三)

增加了部分去重复的功能,以及后缀转中缀显示。

代码语言:javascript代码运行次数:0运行复制
#include <iostream>
#include <stack>
#include <algorithm>
#include <string>
#include <cmath>
#include <time.h>
using namespace std;

struct TOperData
{
    int operType;
    double data;
};

//检查计算的参数是否合法,也可以用于过滤一些重复的表达式
bool checkjisuan(double a, double b, int op)
{
    if (op == '/' && b < 1e-6 && b > -1e-6)
        return false;
    if (op == '-' && b < 1e-6 && b > -1e-6)
        return false;
    if (op == '/' && (fabs(b-1.0f) < 1e-6 || fabs(b+1.0f) < 1e-6))
        return false;
    if (op == '+' || op == '*')
        return a <= b;
    return true;
}
//消除重复
bool checkOp(TOperData computeData[])
{
    for (int i = 0; i < 6; i++)
    {
        int type1 = computeData[i].operType;
        int type2 = computeData[i+1].operType;
        if (type1 == '-' && (type2 == '+' || type2 == '-'))
        {
            return false;
        }
        else if (type1 == '/' && (type2 == '*' || type2 == '/'))
        {
            return false;
        }
    }
    return true;
}

//求值
double jisuan(double a, double b, int op)
{
    switch(op)
    {
    case '+':
        return a + b;
    case '-':
        return a - b;
    case '*':
        return a * b;
    case '/':
        return a / b;
    default:
        return -1;
    }
}
//计算表达式的值
double process(TOperData data[])
{
    int len = 7;
    stack<TOperData> suffix;

    for (int i = 0; i < len; i++)
    {
        if (data[i].operType == 0)
        {
            suffix.push(data[i]);
        }
        else if (data[i].operType > 0)
        {
            if (suffix.empty())
                return false;
            if (suffix.top().operType == 0)
            {
                double a = suffix.top().data;
                suffix.pop();
                if (!suffix.empty() && suffix.top().operType == 0)
                {
                    double b = suffix.top().data;
                    suffix.pop();
                    if (!checkjisuan(b,a,data[i].operType)) return -1;
                    double c = jisuan(b,a,data[i].operType);
                    TOperData opdata;
                    opdata.operType = 0;
                    opdata.data = c;
                    suffix.push(opdata);
                }
                else
                {
                    return -1;
                }
            }
            else
            {
                return -1;
            }
        }
    }
    if (suffix.empty()) return -1;
    if (suffix.top().operType == 0)
    {
        double r = suffix.top().data;
        suffix.pop();
        if (suffix.empty()) return r;
    }
    return -1;
}

int op(char x)
{
    if (x == '+')return 1;
    else if (x == '-')return 1;
    else if (x == '*')return 2;
    else if (x == '/')return 2;
    else return 0;
}
//后缀转中缀
string posttomid(TOperData data[])
{
    stack<char> a, b;
    //后缀转回中缀
    stack<TOperData> ope;
    stack<string> opn;
    string tmp1, tmp2;
    for (int i = 0; i < 7; i++)
    {
        if (data[i].operType == 0)
        {
            char buffer [33];
            itoa (data[i].data,buffer,10);
            string tt = "";
            tt += buffer;
            opn.push(tt);
            ope.push(data[i]);
        }
        else
        {
            if (op(ope.top().operType) != 0 && (op(data[i].operType) > op(ope.top().operType) || (op(data[i].operType) == op(ope.top().operType) && (data[i].operType == '-' || data[i].operType == '/'))))
            {
                tmp2 = "(";
                tmp2 += opn.top();
                tmp2 += ")";
            }
            else
            {
                tmp2 = opn.top();
            }

            opn.pop();
            ope.pop();
            if (op(ope.top().operType) != 0 && op(data[i].operType) > op(ope.top().operType))
            {
                tmp1 = "(";
                tmp1 += opn.top();
                tmp1 += ")";
            }
            else
            {
                tmp1 = opn.top();
            }
            ope.pop();
            opn.pop();
            tmp1 += data[i].operType;
            tmp1 += tmp2;
            opn.push(tmp1);
            ope.push(data[i]);
        }
    }
    string result = opn.top();
    cout<<result<< endl;
    return result;
}

//打印成功的结果
void printResult(TOperData computeData[])
{
    for (int i = 0; i < 7; i++)
    {
        if (computeData[i].operType == 0)
        {
            cout<<computeData[i].data<<" ";
        }
        else
        {
            cout<<(char)computeData[i].operType<<" ";
        }
    }
    cout<<endl;
}


int start(double data[])
{
    int shunxu[][7] = {	1,1,1,1,2,2,2 ,
                        1,1,1,2,1,2,2 ,
                        1,1,1,2,2,1,2 ,
                        1,1,2,1,1,2,2 ,
                        1,1,2,1,2,1,2
                      };
    int operAll[] = {'+','-','*','/'};
    TOperData computeData[7];
    double copydata[4];
    copydata[0] = data[0];
    copydata[1] = data[1];
    copydata[2] = data[2];
    copydata[3] = data[3];
    //5个后缀表达式遍历
    for (int m = 0; m < 5; m++)
    {
        do
        {
            int oper[3];
            for(int n = 0; n < 4; n++)
            {
                oper[0] = operAll[n];
                for(int nn = 0; nn < 4; nn++)
                {
                    oper[1] = operAll[nn];
                    for(int nnn = 0; nnn < 4; nnn++)
                    {
                        oper[2] = operAll[nnn];
                        int j = 0;
                        int k = 0;
                        for (int i = 0; i < 7; i++)
                        {
                            if (shunxu[m][i] == 1)
                            {
                                computeData[i].operType = 0;
                                computeData[i].data = data[j++];
                            }
                            else if (shunxu[m][i] == 2)
                            {
                                computeData[i].operType = oper[k++];
                            }
                        }
                        if (!checkOp(computeData)) continue;
                        double r = process(computeData);
                        if (r-24 > -1e-6 && r-24 < 1e-6)
                        {
                            cout<<copydata[0]<<" "<<copydata[1]<<" "<<copydata[2]<<" "<<copydata[3]<<",";
                            //printResult(computeData);
                            posttomid(computeData);
                            return 1;//如果只要求一个结果,这个地方就可以返回了
                        }
                    }
                }
            }
        }
        while ( next_permutation (data,data+4) );
    }
    return 0;
}

int main(void)
{
    long beginTime =clock();//获得开始时间,单位为毫秒
    double data[4];
    for (int i = 1; i< 14; i++)
    {
        data[0] = i;
        for (int ii = i; ii< 14; ii++)
        {
            data[1] = ii;
            for (int iii = ii; iii< 14; iii++)
            {
                data[2] = iii;
                for (int iiii = iii; iiii< 14; iiii++)
                {
                    data[3] = iiii;
                    double copydata[4];
                    copydata[0] = data[0];
                    copydata[1] = data[1];
                    copydata[2] = data[2];
                    copydata[3] = data[3];
                    start(copydata);
                }
            }
        }
    }
    long endTime=clock();//获得结束时间
    cout<<"time:"<<endTime-beginTime<<endl;
    return 0;
}

部分结果:

1 1 1 8,(1+1+1)*8 1 1 1 11,(1+1)*(1+11) 1 1 1 12,1*(1+1)*12 1 1 1 13,(1+1)*(13-1) 1 1 2 6,2*(1+1)*6 1 1 2 7,(1+2)*(1+7) 1 1 2 8,1*(1+2)*8 1 1 2 9,(1+2)*(9-1) 1 1 2 10,2*(1+1+10)

。。。

大概6s取得单一结果,一共1362个解。

取得全部结果需要14s。其实还是有很多重复。离。需要更细化的过滤。

这部分暂时不做了。有空还是想做一个android的24点小游戏。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-10-11,如有侵权请联系 cloudcommunity@tencent 删除游戏dataintreturn程序