算法练习——“填写运算符”

来源:互联网 发布:centos打包iso文件 编辑:程序博客网 时间:2024/05/14 06:35

题目:
输入五个数,数与数之间用空格分开,然后给出结果,然后在5个数间添加“+”,“-”,“*”,“/”4个运算符,使得等式成立。
例如:
输入:5 5 5 5 5
结果是5:
5+5+5-5-5=5
“+,+,-,-”算一组正确答案
解题思路:

  • 注意问题

    首先我们要清楚,一旦将四个符号填写到四个空格中会形成一个四则运算恒等式,在四则运算中我们要注意俩个问题: - 乘和除法优先级要高于加减法 - 0不能作为除数  所以在编码的时候一定要先考虑这俩个问题。
  • 总体思路

    对于这种问题需要用到枚举的思想,也就是遍历所有的符号分配方式,判断是否满足结果,若满足则视为一个合理的分配方案进行输出。

  • 详细设计
    ♦ 我们所研究的对象是符号分配,所以要将注意力放在符号上,为了方便在后边判断符号添加的合理性,我们最好要有将符号存储在一个字符数组中的意识。且还需要一个数组用来存放符号数组中所有排列组合的下标集(0代表‘+’;1代表‘-’;2代表‘*’;3代表‘/’),然后对每一组进行循环排查。
    ♦除数不能是0
    通过一个判断语句进行筛选,当下标大于3时下一个数不能是0。
    ♦优先级
    设置俩个变量,一个负责加减,另一个负责乘除,最后进行合并。
    代码实现:

// 2017_6_26_Tian.cpp : 定义控制台应用程序的入口点。///***填写运算符:在5   5   5   5   5=5 中添加“+”,“-”,“*”,“/”4个运算符,使得等式成立*/#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){    int num[5];//用于存放输入的数字集    char mark[4]={'+','-','*','/'};//用于存放运算符集    int myMark[4]; //用于存放四个数字:0代表‘+’;1代表‘-’;2代表‘*’;3代表‘/’    int result;//用于存放运算结果    int sign;//用于存放运算符    float left=0,right=1;//left存放上一步运算结果    int count=0;//用于记录结果数    printf("请输入5个整数,中间用空格隔开:");    for(int i=0;i<5;i++){        scanf("%d",&num[i]);    }    printf("请输入一个结果:");    scanf("%d",&result);        //分别将四个符号依次放入符号数组        for(myMark[0]=0;myMark[0]<4;myMark[0]++){            if(myMark[0]<3||num[1]!=0){            for(myMark[1]=0;myMark[1]<4;myMark[1]++){                if(myMark[1]<3||num[2]!=0){                for(myMark[2]=0;myMark[2]<4;myMark[2]++){                    if(myMark[2]<3||num[3]!=0){                    for(myMark[3]=0;myMark[3]<4;myMark[3]++){                        if(myMark[3]<3||num[4]!=0){                        left=0;                        right=num[0];                        sign=1;//初始为正数                        for(int j=0;j<4;j++){                            switch(mark[myMark[j]]){                                case'+':                                    left=left+sign*right;                                    sign=1;                                    right=num[j+1];                                    break;                                case'-':                                    left=left+sign*right;                                    sign=-1;                                    right=num[j+1];                                    break;                                case'*':                                    right=right*num[j+1];                                    break;                                case'/':                                    right=right/num[j+1];                                    break;                            }                        }                        if(left+sign*right==result){                            count++;                            printf("%3d:",count);                            for(int j=0;j<4;j++){                                printf("%d%c",num[j],mark[myMark[j]]);                            }                                printf("%d=%d\n",num[4],result);                          }                        }                      }                    }                  }                }              }            }        }    return 0;}

在循环部分还可以这样写,但是最终的目的还是将符号数组的下标进行排列组合:

    for(int x=0;x<4;x++){        for(int y=0;y<4;y++){            for(int i=0;i<4;i++){                for(int j=0;j<4;j++){                    myMark[0]=x;                    myMark[1]=y;                    myMark[2]=i;                    myMark[3]=j;                    left=0;                    right=num[0];                    sign=1;                    for(int i=0;i<4;i++){                        switch(mark[myMark[i]]){                        case'+':                            left=left+sign*right;                            right=num[i+1];                            sign=1;                            break;                        case'-':                            left=left+sign*right;                            sign=-1;                            right=num[i+1];                            break;                        case'*':                            right=right*num[i+1];                            break;                        case'/':                            right=right/num[i+1];                            break;                        }                    }                    if(left+sign*right==result){                        count++;                        printf("%3d:",count);                        for(int i=0;i<4;i++){                            printf("%d%c",num[i],mark[myMark[i]]);                          }                        printf("%d=%d\n",num[4],result);                    }                }            }        }    }

运行结果:
这里写图片描述

原创粉丝点击