求此题的完整的程序设计

图片说明

// to24point1.cpp : 定义控制台应用程序的入口点。
//
#include <tchar.h>
#include <vector>
#include <string>
using namespace std;
//因为中间结果可能有非整数,所以使用float 保存数值
typedef pair<float,string> VALUE_DESC;
//
typedef vector<VALUE_DESC> VEC_DESC;
/**
 *  \fn string gen_op(char* op,string &desc1,string &desc2)
 *  \brief 生成二值计算的表达式
 *  \param op 操作符 + - * /
 *  \param desc1 第一个操作数的表达式
 *  \param desc2 第二个操作数的表达式
 */
string gen_op(char* op,string &desc1,string &desc2)
{
    string result ="(";
    result.append(op);
    result.push_back(' ');
    result.append(desc1);
    result.push_back(' ');
    result.append(desc2);
    result.push_back(')');
    return result;
}

/**
 *  \fn VEC_DESC four_calc(VALUE_DESC &a1,VALUE_DESC &a2)
 *  \brief 四则运算
 *  \param a1 --第一个值和它的表达式
 *  \param a2 --第二个值和它的表达式
 *  \return 值和它的表达式
 */
VEC_DESC four_calc(VALUE_DESC &a1,VALUE_DESC &a2)
{
#define APPEND_RESULT(vec,op,a1,a2) vec.push_back(make_pair(a1.first##op##a2.first,gen_op(#op,a1.second,a2.second)));
    VEC_DESC result ;
    char op[4] ={'+','-','*','/'};
    for(int i=0;i<4;i++)
    {
        char c = op[i];
        switch(c)
        {
        case '+':
            {
                APPEND_RESULT(result,+,a1,a2);
                break;
            }
        case '-':
            {           
                APPEND_RESULT(result,-,a1,a2);
                APPEND_RESULT(result,-,a2,a1);
                break;
            }
        case '*':
            {   
                APPEND_RESULT(result,*,a1,a2);              
                break;
            }   
        case '/':
            {           
                if(a1.first!=0)
                {
                    APPEND_RESULT(result,/,a2,a1);
                }
                if(a2.first!=0)
                {
                    APPEND_RESULT(result,/,a1,a2);
                }
                break;
            }

        }
    }
    return result;
}
/**
 *  \fn void calc(VALUE_DESC value,VEC_DESC &vec,VEC_DESC &result)
 *  \brief 递归计算vec和输入的value 之间的值,结果保存result
 *  \param value - 输入的值,初始值为0
 *  \param vec - 一组数,初始为4个数
 *  \param result - 结果为最终通过四则混合运算计算的可能结果,很多很多
 */
void calc(VALUE_DESC value,VEC_DESC &vec,VEC_DESC &result)
{
    if(value.first==0)//还没有中间结果
    {
        if(vec.size()==1) //得到结果
        {
            result.push_back(vec[0]);
            return ;
        }
        for(size_t i=0;i<vec.size();i++) //顶层的计算,4个则可能有4种取的可能
        {
            VEC_DESC t = vec;
            t.erase(t.begin()+i);
            calc(vec[i],t,result);//输出可能的值
        }
    }
    else
    {
        //有了中间结果,从vec中获取1个元素,参与运算,结果继续运算
        for(size_t i=0;i<vec.size();i++) 
        {
            VEC_DESC t = vec;
            t.erase(t.begin()+i);
            //中间结果
            VEC_DESC vcalc=four_calc(value,vec[i]);
            for(size_t j=0;j<vcalc.size();j++)
            {
                VEC_DESC tt = t;
                tt.push_back(vcalc[j]);
                //中间结果,剩下的元素,结果
                calc(make_pair(0.0,string("")),tt,result);
            }
        }
    }
}
//初始化数据
void init_vec_desc(VEC_DESC &vec,int value[],int len)
{
    for(int i=0;i<len;i++)
    {
        char buf[10]={};
        itoa(value[i],buf,10);

        vec.push_back(make_pair(value[i],buf));
    }
}
//获得等于24的结果
VALUE_DESC get_correct_value(VEC_DESC &r)
{
    for(size_t i=0;i<r.size();i++)
    {
        if(r[i].first >=24.0000000 && r[i].first<24.00000001 )
        {
            return r[i];
        }
    }
    return make_pair(0,"");
}
int to24(VEC_DESC &vec)
{
    VEC_DESC r;
    calc(make_pair(0.0,string("")),vec,r);
    VALUE_DESC result = get_correct_value(r);
    if(result.first==0)
    {
        printf("[%d %d %d %d] cannot calculate 24\n",(int)vec[0].first,(int)vec[1].first,(int)vec[2].first,(int)vec[3].first);
    }
    else
    {
    printf("[%d %d %d %d] : %s\n",(int)vec[0].first,(int)vec[1].first,(int)vec[2].first,(int)vec[3].first,result.second.c_str());
    }
    return 0 ;
}
void test()
{
    VEC_DESC input;
    VEC_DESC r; 
    int buf[][4]={
            {5,1,4,2},
            {3,3,3,1},
            {5,5,5,1},
            {1,1,6,8},
            {1,1,6,9},
            {1,1,7,10},
            {1,1,8,8},
    };
    for(int i=0;i<sizeof(buf)/sizeof(buf[0]);i++)
    {
        input.clear();
        init_vec_desc(input,buf[i],4);
        to24(input);
    }
}
void test1()
{
    int i,j,k,m;
    for(i=1;i<=13;i++)
        {
        for(j=1;j<=13;j++)
            {
            for(k=1;k<=13;k++)
                {
                for(m=1;m<=13;m++)
                    {
                    VEC_DESC input;
                    int buf[4]={i,j,k,m};
                    init_vec_desc(input,buf,4);
                    to24(input);
                    }
                }
            }
        }
}
int _tmain(int argc, _TCHAR* argv[])
{
    test1();
    return 0;
    VEC_DESC input;
    VEC_DESC r;
    int buf[4]={5,1,4,2};
    printf("\nPlease input 4 number:");
    scanf("%d%d%d%d",&buf[0],&buf[1],&buf[2],&buf[3]);
    init_vec_desc(input,buf,4);
    to24(input);

    return 0;
}


https://blog.csdn.net/justin_bkdrong/article/details/45843051

这个才是“完整”代码,如果用VS2019编译,基本不用改。

#define _CRT_SECURE_NO_WARNINGS
#include <time.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

int const NUMBERCOUNT = 4;
float const RESULT = 24;
bool isHit = false;
bool showanswer = true;

char* ExpressPool;
int PoolIdx;
int MAX_RESULT = 1500;


enum OPT {
    PLU,//加
    MIN,//减
    MINBY,//被减
    MUL,//乘
    DIV,//除
    DIVBY//被除
};


float cal(int ncount, float* nums, char* exps)
{

    float a, b;
    if (ncount == 2)
    {
        a = nums[0];
        b = nums[1];

        OPT opt;
        float result = 0.0f;

        for (opt = PLU; opt <= DIVBY; opt = (OPT)(opt + 1))
        {
            switch (opt)
            {
            case PLU:
                result = a + b;
                if (result == RESULT)
                {
                    sprintf(ExpressPool + PoolIdx * 32, "%s+%s", exps, exps + 32);
                    PoolIdx++;
                    sprintf(ExpressPool + PoolIdx * 32, "%s+%s", exps + 32, exps);
                    PoolIdx++;
                    isHit = true;
                }
                break;
            case MIN:
                result = a - b;
                if (result == RESULT)
                {
                    sprintf(ExpressPool + PoolIdx * 32, "%s-%s", exps, exps + 32);
                    PoolIdx++;
                    isHit = true;
                }
                break;
            case MINBY:
                result = b - a;
                if (result == RESULT)
                {
                    sprintf(ExpressPool + PoolIdx * 32, "%s-%s", exps + 32, exps);
                    PoolIdx++;
                    isHit = true;
                }
                break;
            case MUL:
                result = a * b;
                if (result == RESULT)
                {
                    sprintf(ExpressPool + PoolIdx * 32, "%s*%s", exps, exps + 32);
                    PoolIdx++;
                    sprintf(ExpressPool + PoolIdx * 32, "%s*%s", exps + 32, exps);
                    PoolIdx++;
                    isHit = true;
                }
                break;
            case DIV:
                if (b == 0)continue;
                result = a / b;
                if (result == RESULT)
                {
                    sprintf(ExpressPool + PoolIdx * 32, "%s/%s", exps, exps + 32);
                    PoolIdx++;
                    isHit = true;
                }
                break;
            case DIVBY:
                if (a)continue;
                result = b / a;
                if (result == RESULT)
                {
                    sprintf(ExpressPool + PoolIdx * 32, "%s/%s", exps + 32, exps);
                    PoolIdx++;
                    isHit = true;
                }
                break;
            }
        }

    }
    else
    {
        for (int i = 0; i < ncount; i++)
        {
            for (int j = 0; j < ncount; j++)
            {
                if (i != j)
                {
                    int newcount = ncount - 1;
                    float* num = new float[newcount];
                    char* newexps = (char*)malloc(32 * newcount);
                    memset(newexps, 0, 32 * newcount);
                    int idx = 1;
                    for (int m = 0; m < ncount; m++)
                    {
                        if (m != i && m != j)
                        {
                            num[idx] = nums[m];
                            strcpy(newexps + idx * 32, exps + m * 32);
                            idx++;
                        }
                    }
                    OPT opt;
                    for (opt = PLU; opt <= DIVBY; opt = (OPT)(opt + 1))
                    {
                        switch (opt)
                        {
                        case PLU:
                            num[0] = nums[i] + nums[j];
                            sprintf(newexps, "(%s+%s)", exps + i * 32, exps + j * 32);
                            break;
                        case MIN:
                            num[0] = nums[i] - nums[j];
                            sprintf(newexps, "(%s-%s)", exps + i * 32, exps + j * 32);
                            break;
                        case MINBY:
                            num[0] = nums[j] - nums[i];
                            sprintf(newexps, "(%s-%s)", exps + j * 32, exps + i * 32);
                            break;
                        case MUL:
                            num[0] = nums[i] * nums[j];
                            sprintf(newexps, "(%s*%s)", exps + i * 32, exps + j * 32);
                            break;
                        case DIV:
                            if (nums[j] == 0)continue;
                            num[0] = nums[i] / nums[j];
                            sprintf(newexps, "(%s/%s)", exps + i * 32, exps + j * 32);
                            break;
                        case DIVBY:
                            if (nums[i] == 0)continue;
                            num[0] = nums[j] / nums[i];
                            sprintf(newexps, "(%s/%s)", exps + j * 32, exps + i * 32);
                            break;
                        }
                        cal(newcount, num, newexps);
                    }
                    free(newexps);
                    delete(num);
                }
            }
        }
    }

    return 0;
}

int autoanswer(float* num)
{
    int ret = 0;    
    ExpressPool = (char*)malloc(MAX_RESULT * 32);
    memset(ExpressPool, 0, MAX_RESULT * 32);
    PoolIdx = 0;
    char* exps = (char*)malloc(32 * NUMBERCOUNT);
    memset(exps, 0, 32 * NUMBERCOUNT);
    for (int i = 0; i < NUMBERCOUNT; i++)
    {
        if ((exps + i * 32) != 0)
            sprintf(exps + i * 32, "%d", (int)num[i]);
    }
    isHit = false;
    cal(NUMBERCOUNT, num, exps);
    free(exps); 
    if (!isHit)
    {
        if (showanswer)
        {
            printf("无解!\n");
        }
    }
    else
    {

        for (int i = 0; i < MAX_RESULT; i++)
        {
            char firstchar = *(ExpressPool + i * 32);
            if (firstchar != '\0')
            {
                if (showanswer)
                {
                    printf("%s = %d\n", ExpressPool + i * 32, (int)RESULT);
                }
                ret++;
                for (int j = i + 1; j < MAX_RESULT; j++)
                {
                    char newfirstchar = *(ExpressPool + j * 32);
                    if (newfirstchar != '\0')
                    {
                        char* str1 = (char*)(ExpressPool + i * 32);
                        char* str2 = (char*)(ExpressPool + j * 32);
                        int cmpresult = strcmp(ExpressPool + i * 32, ExpressPool + j * 32);
                        if (cmpresult == 0)
                        {
                            memset(ExpressPool + j * 32, '\0', 32);
                        }
                    }
                }
            }
        }
    }
    free(ExpressPool);
    return ret;
}


int main() {

    float num[NUMBERCOUNT];

    srand((unsigned int)(time(NULL)));
    char c;
    printf("\n\n");
    printf("**********************************************************\n");
    printf("*                                                        *\n");
    printf("*                        计算24游戏                      *\n");
    printf("*                                                        *\n");
    printf("*    随机产生4个(0-9)的数字,判断是否能通过+-*/得到24    *\n");
    printf("*                                                        *\n");
    printf("*                        茂大叔提供                      *\n");
    printf("*                                                        *\n");
    printf("**********************************************************\n\n");
    printf("[enter]=随机计算;a=用户答题;q=退出\n");
    printf("请输入命令:");
    c = getchar();
    while (c != 'q') {
        showanswer = true;
        printf("备选数字为:");
        for (int i = 0; i < NUMBERCOUNT; i++)
        {
            num[i] = (float)(rand() % 9 + 1);
            printf(" %d", (int)num[i]);
        }

        if (c == 'a')
        {
            bool correct = false;
            showanswer = false;
            char ans[32] = "null";
            int ret = autoanswer(num);
            while (!correct)
            {
                printf("\n请输入你的答案(除最后一步外,每一个步骤均须用括号包围,输入0代表无解,输入q代表放弃):\n");
                scanf("%s", ans);
                getchar();
                if (ans[0] == 'q')
                {
                    free(ExpressPool);
                    showanswer = true;
                    printf("正确答案可以为:\n");
                    autoanswer(num);
                    printf("共计 %d 条:\n", ret);
                    break;
                }
                else
                {

                    if (!isHit && ans[0] == '0')
                    {
                        correct = true;
                    }
                    else
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            char firstchar = *(ExpressPool + i * 32);
                            if (firstchar != '\0')
                            {
                                char* str1 = (char*)(ExpressPool + i * 32);

                                int cmpresult = strcmp(ExpressPool + i * 32, ans);
                                if (cmpresult == 0)
                                {
                                    correct = true;
                                }
                            }
                        }
                    }
                    if (correct)
                    {
                        printf("\n你真棒!\n");
                    }
                    else
                    {
                        printf("\n输入错误,请重试!\n");
                    }
                }
            }
        }
        if (c == '\n')
        {
            printf("\n不尝试自己做一做么?回车看答案!\n");
            getchar();
            printf("答案可以为:\n");
            int ret = autoanswer(num);
            printf("共计 %d 条:\n", ret);

        }
        if (c == 'm')
        {

            for (int n1 = 1; n1 < 10; n1++)
                for (int n2 = 1; n2 < 10; n2++)
                    for (int n3 = 1; n3 < 10; n3++)
                        for (int n4 = 1; n4 < 10; n4++)
                        {
                            printf("\n备选数:%d %d %d %d\n======================\n", n1, n2, n3, n4);
                            num[0] = (float)n1;
                            num[1] = (float)n2;
                            num[2] = (float)n3;
                            num[3] = (float)n4;
                            int ret = autoanswer(num);
                            printf("共计 %d 条:\n", ret);
                        }
        }
        printf("\n[enter]=随机计算;a=用户答题;q=退出\n");
        printf("请输入命令:");

        c = getchar();
    }
    printf("再见~!");
    return 0;
}