“程序设计(Ⅱ)”综合编程实验报告 ( 2012 - 2013 学年第 2 学期) 实验项目名称: 值班安排 一、实验内容与要求 医院有 A、B、C、D、E、F、G 7 位大夫,在一星期内(星期一至星期天)每 人要轮流值班一天,如果已知: (1)A 大夫比 C 大夫晚 1 天值班; (2)D 大夫比 E 大夫晚 1 天值班; (3)E 大夫比 B 大夫早 2 天值班 (4)B 大夫比 G 大夫早 4 天值班; (5)F 大夫比 B 大夫晚 1 天值班; (6)F 大夫比 C 大夫早 1 天值班; (7)F 大夫星期四值班。 就可以确定周一至周日的值班人员分别为:E、D、B、F、C、A、G。 编写程序,根据输入的条件,输出星期一至星期天的值班人员。 输入数据时,先输入一个整数 n,再输入 n 组条件,要求能够根据输入的条 件确定唯一的值班表,且输入的 n 组条件中能够直接或间接得到任意两位大夫的 关联关系,例如上面的条件(2)直接显示了 D 与 E 间的关系,而通过条件(1)、 (6)、(5)可以间接得到 A 与 B 的关系。 条件的输入格式有 2 种: 格式 1:编号 比较运算符 编号 天数 其中比较运算符有 2 种:> 或 < ,分别表示“早”或“晚” 例如:AB2 B>G4 FC1 F=4 EDBFCAG 二、系统设计 1、解题思路 通过寻找有等号的条件,确定其医生的位置,然后把这个医生及其位置作为 已知的结点,寻找与该医生有关的条件,确定另一位医生的位置,并把该位医生 作为结点,继续寻找,以此递归。 2、数据结构描述 可以定义一个二维字符数组保存条件数据,大小为 10*20,但从 a[1]开始存 放,以便与输入数据(位置值)匹配,另外用 a[][0]来标记条件,还有定义为 全局变量,因为函数里要用到。 3、程序框架结构 定义全局字符数组 s[30]来存放排好序的医生的位置。 定义 void func(char node,int ka); 4、关键算法描述 (1)初始化用来存放顺序的数组为'0' for(i=0;i<=29;i++)//初始化用来存放顺序的数组为'0' s[i]='0'; (2)存放测试数据的条件及标记这些条件 for(i=1;i<=n;i++)//存放测试数据的条件及标记这些条件 { a[i][0]='0'; scanf(%s,&a[i][1]); } (3)寻找条件中有等于号的,确定该位医生的值班时间,并通过该位医生 确定其他与这位医生有关医生的值班时间 for(i=1;i<=n;i++)//寻找条件中有等于号的,确定该位医生的值班时间, //并通过该位医生确定其他与这位医生有关医生的值班时间 { if(a[i][2]=='=') { ka=a[i][3]-'0'; s[ka]=a[i][1]; node=a[i][1]; a[i][0]='1';//把已确定时间的条件标记为'1',避免再次 确定位置(避免重复搜索该条件) func(node,ka);//调用函数,确定与该医生有关系的医生的 值班时间 } } (4) 考虑有些条件没有等于号,且还未确定值班时间的医生,通过假设该医 生的位置,同时确定与该医生有关的医生值班时间 for(i=1;i<=n;i++)//考虑有些条件没有等于号,且还未确定值班时间的医 生,通过假设该医生的位置,同时确定与该医生有关的医生值班时间 { if(a[i][0]=='0')//判断是否被标记过 { node=a[i][1]; s[20]=node;//假设该医生的时间是在 20 ka=20;//记录该医生的位置 func(node,ka);//同过函数,确定与该医生有关的医生与该 医生的相对位置 } } (5) 星期一到星期五是否都有医生值班 for(i=1;i<=7;i++)//判断星期一到星期五是否都有医生值班 if(s[i]=='0') { aa=i; flag=1;//如果哪一天没人值班,记下那一天的时间并把 flag 标记为 1; break; } (6) 通过假设的位置,填充到数组的相应位置 if(flag==1)//通过假设的位置,填充到数组的相应位置 { for(i=10;i<=29;i++) if(s[i]!='0') { ab=i; break; } for(i=aa;i<=7;i++) { if(s[i]=='0') s[i]=s[ab-aa+i]; } } (7) 输出医生值班的顺序表 for(i=1;i<=7;i++)//输出医生值班的顺序表 printf(%c,s[i]); putchar(10);//换行 (8) 实现用已知医生及位置确定与其相关的医生的位置 void func(char node,int ka)//实现用已知医生及位置确定与其相关的医 生的位置 { char node1,ka1,kb1; int j; for(j=1;j<=n;j++) { if(a[j][0]!='1')//判断是否已确定位置的条件 { if(a[j][1]==node||a[j][3]==node)//判断是否与已知的医生 有关的条件 { a[j][0]='1';//把该条件标记为'1',避免再次使用 //确定该条件中还未确定位置的另一位医生的位置 if(a[j][1]!=node) { if(a[j][2]=='<') kb1=a[j][4]-'0'; else kb1=-(a[j][4]-'0'); s[ka+kb1]=a[j][1]; node1=a[j][1]; ka1=ka+kb1; func(node1,ka1);//把该医生作为已知位置的医生来确 定其他与这医生有关的医生 } else { if(a[j][2]=='<') kb