下面再演示一个用枚举算法解决问题的实例,具体的题目是:在下面的算式中适当地添加“+、-、×、÷”运算符,使等式成立(不使用括号)。
分析该题,这是1个由5个数组成的算式,一共需要填入4个运算符,而每两个数之间的运算符有4种选择(加、减、乘、除),通过循环程序可枚举填入这4个运算符之一,然后再判断算式是否成立。
由于算术表达式的特殊性,在编程求解这个算式时,需要注意以下两点:
■ 当填入除号时,要求右侧的数不能为0。
■ 乘除的运算级别比加减高。
对于第1点,在程序中添加一个判断语句,如果试算时填入的运算符是除(/),则其后面的数不能为0,若为0,则跳过该次试算,直接进行下一轮计算。
对于第2点,处理起来就要麻烦一点。考虑以下的算式:
技巧 在程序中可设置两个变量left和right,left用来保存上次的运算结果(下次运算的左侧内容),right用来保存下次将参加运算的数据(即下次运算的右侧内容)。
对于前两个运算符(加和减),可以很简单地进行运算,对于第3个运算符(乘),因为其运算级别比前面的减要高,因此需要先计算减号右侧的算式,这时可保持左侧内容(left变量)为“5+5”的值,直接用右侧内容(right变量的值)乘以下一个运算数据,并将结果保存在右侧内容(right变量)中。按同样的方式处理 […](/),则其后面的数不能为0,若为0,则跳过该次试算,直接进行下一轮计算。
对于第2点,处理起来就要麻烦一点。考虑以下的算式:
技巧 在程序中可设置两个变量left和right,left用来保存上次的运算结果(下次运算的左侧内容),right用来保存下次将参加运算的数据(即下次运算的右侧内容)。
对于前两个运算符(加和减),可以很简单地进行运算,对于第3个运算符(乘),因为其运算级别比前面的减要高,因此需要先计算减号右侧的算式,这时可保持左侧内容(left变量)为“5+5”的值,直接用右侧内容(right变量的值)乘以下一个运算数据,并将结果保存在右侧内容(right变量)中。按同样的方式处理 […]
1: #include <stdio.h>
2: int main()
3: {
4: int j,i[5];
4 int j,i[5]; //循环变量 ,数组i用来表示4个运算符
5: int sign; //累加运算时的符号
6: int result; //保存运算式的结果值
7: int count=0; //计数器,统计符合条件的方案
8: int num[6]; //保存操作数
9: float left,right; //保存中间结果
10: char oper[5]={' ','+','-','*','/'}; //运算符
11: printf("请输入5个数:");
12: for(j=1;j<=5;j++)
13: scanf("%d",&num[j]);
14: printf("请输入结果:");
15: scanf("%d",&result);
16: for(i[1]=1;i[1]<=4;i[1]++) //循环4种运算符,1表示+,2表示-,3表示*,4表示/
17: {
18: if((i[1]<4) || (num[2]!=0)) //运算符若是/,则第二个运算数不能为0
19: {
20: for(i[2]=1;i[2]<=4;i[2]++)
21: {
22: if((i[2]<4) || (num[3]!=0))
23: {
24: for(i[3]=1;i[3]<=4;i[3]++)
25: {
26: if((i[3]<4) || num[4]!=0)
27: {
28: for(i[4]=1;i[4]<=4;i[4]++)
29: {
30: if((i[4]<4) || (num[5]!=0))
31: {
32: left=0;
33: right=num[1];
34: sign=1;
35: for(j=1;j<=4;j++)
36: {
37: switch(oper[i[j]])
38: {
39: case '+':
40: left=left+sign*right;
41: sign=1;
42: right=num[j+1];
43: break;
44: case '-':
45: left=left+sign*right;
46: sign=-1;
47: right=num[j+1];
48: break; //通过f=-1实现减法
49: case '*':
50: right=right*num[j+1];
51: break; //实现乘法
52: case '/':
53: right=right/num[j+1]; //实现除法
54: break;
55: }
56: }
57: if(left+sign*right==result)
58: {
59: count++;
60: printf("%3d:",count);
61: for(j=1;j<=4;j++)
62: printf("%d%c",num[j],oper[i[j]]);
63: printf("%d=%d\n",num[5],result);
64: }
65: }
66: }
67: }
68: }
69: }
70: }
71: }
72: }
73: if(count==0)
74: printf("没有符合要求的方法!\n");
75: getch();
76: return 0;
77: }
73: if(count==0)
74: printf("没有符合要求的方法!\n");
75: getch();
76: return 0;
77: }73: if(count==0)
74: printf("没有符合要求的方法!\n");
75: getch();
76: return 0;
77: }
程序说明】
■ 第4~10行定义程序中需要使用的变量,各变量的作用在右侧的注释中已说明。
■ 第11~15行接收用户输入的运算数据和结果值。
■ 第16、20、24、28行使用循环语句循环处理加、减、乘、除4种运算符。
■ 第18、22、26、30行使用条件判断语句,处理除号后的数字不能为0的情况。
■ 第35~56行将4种运算符填入对应位置,并对算式进行运算。
■ 第57~64行进行判断,如果算式的计算结果与输入的结果相符,则表示找到一种解法,输出该解。
编译执行以上代码,将计算数据和结果都输入为5,其结果如图1-6所示。
摘自:《零基础学算法 第3版 》 — 戴艳
在豆瓣阅读书店查看:https://read.douban.com/ebook/8190312/
本作品由华章数媒授权豆瓣阅读全球范围内电子版制作与发行。
© 版权所有,侵权必究。