基于递归的构建等式问题的求解方法(C语言版)

题目说明

为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要经常性地进行体力训练和智力训练!某批警察叔叔正在进行智力训练:

    1 2 3 4 5 6 7 8 9 = 110;

请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能填入其它符号)。之间没有填入符号的数字组合成一个数,例如:12+34+56+7-8+9 就是一种合格的填法;123+4+5+67-89 是另一个可能的答案。

请你利用计算机的优势,帮助警察叔叔快速找到所有答案。

每个答案占一行。形如:

    12+34+56+7-8+9

    123+4+5+67-89

程序清单

#include <stdio.h>

// 递归方式构造表达式
int constructExpression(int n, int src[],int exp[], int target) 
{
    int i,j;                                                       // 用于循环中使用的循环变量
    int sign[3] = {0, -1, -2};                            // 0代表没有符号,-1代表加号,-2代表减号 
    exp[2*n-2] = src[n-1];
    if(n==9){                                                  //   测试到第几个数字,9表示最后一个数字,递归出口 
        if(getResult(exp, target)){
            printExpression(exp, target);    
        }
        return 0;
    }else{
        for(i=0;i<3;i++){                                    //    填充符号,递归构造表达式
            if(sign[i]==0){                                    //    填充符号
                exp[2*n-1] = 0;                                 
            }else if(sign[i]== -1){
                exp[2*n-1] = -1;    
            }else if(sign[i]== -2){
                exp[2*n-1] = -2;    
            }
            constructExpression(n+1, src, exp, target);    //    递归构造后部表达式
        }
    }
    return 0;
}

// 计算表达式结果 

int getResult(int exp[], int target){
    int i;
    int index = 0;                // 新数组的索引
    int newexp[17];
    int result = 0;
    
    // 将表达式转换成标准算式 
    for(i=0;i<17;i++){
        if(exp[i] != 0){
            newexp[index] = exp[i];
            index ++;
        }else{
            index --;                      // 当遇到0时,说明前后数字应该组合后存入,而不是只存0前面的数
            newexp[index] = newexp[index] * 10 + exp[i+1];        // 0左面的数 * 10+0右面的数
            i++;                                                                              // 跳过0右面的数
            index ++;
        }        
    }

    // 计算表达式结果 
    result = newexp[0];
    for(i=1;i<=index/2;i++){
        if(newexp[2*i-1] == -1){
            result += newexp[2*i];
        }else {
            result -= newexp[2*i];
        }
    }
    
    // 判断是否是所需的表达式
    if(result == target){
        return 1;
    } else{
        return 0;
    }

// 打印结果输出表达式 
int printExpression(int exp[],int target){
    int i;
    for(i=0;i<17;i++){
        if(exp[i] == 0){
            continue;
        }else if(exp[i] == -1){
            printf(" %c ", '+');
        }else if(exp[i] == -2){
            printf(" %c ", '-');
        }else{
            printf("%d", exp[i]);
        }        
    }
    printf(" = %d\n", target);
    return 0;
}

int main(){
    int src[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int exp[17]; 
    constructExpression(1, src, exp, 110);
    return 0;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tangguofeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值