4.6 解决更多问题
4.6.1 结构图中的数据流信息
在图4-6中,结构图中的数据流信息给出了每个单独的算法步骤的输入和输出。数据流信息是系统文档很重要的一部分,因为它表明了每个算法步骤处理的程序变量,以及处理这些变量的方式。如果某个步骤给一个变量赋予了新值,那么这个变量就被当作该步骤的一个输出。如果某个步骤显示了变量的值或者在计算中使用了变量而没有改变变量的值,这个变量就被当作该步骤的一个输入。
图4-7表明,一个变量对算法的不同子问题可以具有不同的角色。在原始问题陈述的语境中,previous和current是问题输入(程序用户提供的数据)。然而,在子问题“获取数据”的语境中,这个子问题的任务是为主程序的previous和current提供值;因此,previous和current被当作这个步骤的输出。在子问题“计算用量水费”的语境中,这个子问题的任务是使用previous和current来计算use_charge,因此它们是这个步骤的输入。其他变量的角色以相同的方式随着问题步骤的变化而改变。
4.6.2 使用子函数修改程序
新出现的问题经常被证实是已经解决的某个问题的变体。因此,解决问题的一个重要技巧是能够识别出一个问题和以前解决的另一个问题类似。在学习这门课程时,读者可以开始构建自己的程序库或函数库。应该尽可能尝试采用或复用已经成功的程序的一部分。
由于程序员和程序用户经常想在使用程序后对程序进行小的改进,编写容易修改以适应其他情况的程序是明智的。如果最初的程序设计良好并模块化了,程序员能够付出最小的努力就适应计划的改变。就像在解决下一个问题时将会看到的那样,当需要进行修改时,只修改一两个函数而不是重写整个程序是可能的。
实例研究:具有节约需求的水费问题
问题
需要对水费问题程序进行修改,使得没有达到节约需求的用户被收取的费用是满足需求的用户的两倍。为了享有较低的使用费率(每千加仑$1.10),要求这个地区的住户每季度使用的水量不超过去年同期的95%。
分析
这个问题是上一小节解决的水费问题的一个变体。满足节约方针的客户按每千加仑$1.10的基本费率收取费用;不满足要求的客户按两倍的费率收取费用。通过添加去年的使用量作为问题输入并修改函数comp_use_charge可以解决这个问题。函数comp_use_charge的附加数据需求和修改后的算法如下。
附加数据需求
问题常量
OVERUSE_CHG_RATE 2.0 /* double use charge as non-conservation
penalty */
CONSERV RATE 95 /* percent of last year's use
allowed this year */
问题输入
int use_last_year /* use for same quarter
last year */
comp_use_charge的算法
(1) used等于current – previous
(2) 如果满足方针
use_charge等于used * PER_1000_CHARGE
否则
use_charge等于used * overuse_chg_rate * PER_1000_CHG
图4-9给出了修改后的函数。如果条件
(used <= CONSERV_RATE / 100.0 * use_last_year)
为true,就满足节约方针并且用量水费按照以前的方式计算;否则客户被认为过度用水,在计算用量水费时将把过度使用费率计算在内。
必须修改comp_use_charge的函数原型以匹配它的函数首部,并以
use_charge = comp_use_charge(previous, current, use_last_year);
替换图4-7中对函数comp_use_charge的调用。要完成修订的程序,需要修改函数instruct_water来显示新的用户指示,还要修改主函数提示输入use_last_year。
|
490. /* 491. * Computes use charge with conservation requirements 492. * Pre: previous, current, and use_last_year are defined. 493. */ 494. double 495. comp_use_charge(int previous, int current, int use_last_year) 496. { 497. int used; /* gallons of water used (in thousands) */ 498. double use_charge; /* charge for actual water use */ 499. used = current - previous; 500. if (used <= CONSERV_RATE / 100.0 * use_last_year) { 501. /* conservation guidelines met */ 502. use_charge = used * PER_1000_CHG; 503. } else { 504. printf("Use charge is at %.2f times ", OVERUSE_CHG_RATE); 505. printf("normal rate since use of\n"); 506. printf("%d units exceeds %d percent ", used, CONSERV_RATE); 507. printf("of last year's %d-unit use.\n", use_last_year); 508. use_charge = used * OVERUSE_CHG_RATE * PER_1000_CHG; 509. } 510. 511. return (use_charge); 512. } |
图4-9 修改后的函数comp_use_charge
练习
编程
1. 为具有节约需求的水费问题给出完整的程序。







