D题:REPEAT 程序
问题描述:
附件 prog.txt 中是一个用某种语言写的程序。(prog文件点击这里)
其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,
从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。
例如如下片段:
REPEAT 2:
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 7
A = A + 8
A = A + 9
该片段中从 A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的循环两次中。
REPEAT 6所在的行到 A = A + 7 所在的行都在 REPEAT 5循环中。
A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。
请问该程序执行完毕之后,A 的值是多少?
思路:
1、先观察这个式子,一行一行读入的话,即42+5(256)+7*(52)+82+9=403。
注意:403只是这部分代码的答案
2、用fget函数读入这个文件,用字符数组buff存储,计算的时候转换成数字计算,所以要写一个转换函数change()。
3、从文件的第二行开始,一行一行的读
4、遇到R,向右挪7个字符,算出乘数
5、遇到“A=”,右挪8个字符,到等式最右边的常数,先算 常数 * 第4步的乘数,循环,最后算整个等式。
6、把A=0 带进去,解出整个A答案。
(注意,一开始从组数buff[0] 读到A的话,代表这个等式是不计入循环。)
代码:
#include<stdio.h>
#include <string.h>
using namespace std;
int change(char n){
switch(n){ //读入是字符,而计算是数字,所以先定义字符转数字函数
case('1'): return 1;
case('2'): return 2;
case('3'): return 3;
case('4'): return 4;
case('5'): return 5;
case('6'): return 6;
case('7'): return 7;
case('8'): return 8;
case('9'): return 9;
}
}
int main(){
char src[]="E:/prog.txt"; //定义文件流路径
FILE *f0=NULL;
f0=fopen(src,"r");//定义,初始化,并写入f0
char buff[255]; //定义buff数组
fgets(buff,255, f0);//fgets函数的用法,一行一行读入
int fact[10]; //代码中Repeat后面跟的,乘数,字符1~9,对应f[0]-f[9],要转换成数字1~9。
int count=0;//count表示,当前Repeat的层级
int a=0; //根据题意,知道 A=0
while(fgets(buff,255,f0)){
//跳过第一行有0的数,从第二行开始读
//printf("%s",&buff); 这里可以试着,验证一下
int p=0;
while(buff[p]==' ')
p++;//每读一行时,从buff数组下标0开始读
if(buff[p]=='R'){
count=(p==0?0:p/4);//读到Repeat时,根据缩进判断层级
fact[count]=change(buff[p+7]);
//从R后数7个字符,就是当前层数代表的乘数字符1~9,转换成数字,赋值给fact
continue;//结束当前行,开始读下一行代码
}
else if(buff[p]=='A'){
count=(p==0?-1:p/4-1);//注意:第一个字母是A的情况下,不计入循环运算
//读到A时,根据缩进(前面有几个空)判断层级
int fa=1;
if(p!=-1)//第一个字母是不是A,在循环里才执行
for(int i=0;i<=count;i++)
fa*=fact[i];//A等于当前层时,根据Repeat的乘数,先相乘
a+=fa*change(buff[p+8]);//最后相乘 "A=" 这个等式往后数8个字符的数,转换成数字。
//最后相加题目中给的A=0;
}
}
printf("%d",a); //输出A
return 0;
}