8.6.4 使用CBox类
假设我们在包装糖果。这些糖果都在破碎机上各占用1.5英寸长、1英寸宽、1英寸高的空间。我们可以使用4.5英寸长、7英寸宽、2英寸高的标准糖果盒,现在想知道盒中能够容纳多少块糖果,以便制定价格。我们还有一种标准的纸板箱,长2英尺6英寸,宽18英寸,深18英寸。我们想知道该纸板箱可以容纳多少个糖果盒,装满之后有多大的未用空间。
万一标准糖果盒不是合适的解决方案,我们还想知道定制多大尺寸的糖果盒才合适。如果糖果盒的长度在3~7英寸之间,宽度在3~5英寸之间,高度在1~2.5英寸之间(这些尺寸可以以半英寸为步距变化),那么就能卖上好价钱。糖果盒中至少需要30块糖果,因为这是绝大多数顾客一次消费的最低数量。另外,糖果盒不应该有剩余空间,那样将使消费者感到上当受骗。理想情况下我们还希望纸板箱塞满,这样糖果盒将不会到处晃荡。我们也不希望包装得太紧,那样将增加包装的难度,因此如果纸板箱的剩余空间小于一个糖果盒的体积,就可以说没有浪费空间。
使用CBox类,该问题很容易解决,解决方案由下面的main()函数给出。像以前一样,右击Solution Explorer窗格中的Source Files,从弹出的上下文菜单中选择适当的菜单项,给本项目添加一个新的C++(www.cppentry.com)源文件Ex8_08.cpp,然后输入下面显示的代码:
- // Ex8_08.cpp
- // A sample packaging problem
- #include <iostream>
- #include "Box.h"
- #include "BoxOperators.h"
- using std::cout;
- using std::endl;
-
- int main()
- {
- CBox candy(1.5, 1.0, 1.0); // Candy definition
- CBox candyBox(7.0, 4.5, 2.0); // Candy box definition
- CBox carton(30.0, 18.0, 18.0); // Carton definition
-
- // Calculate candies per candy box
- int numCandies = candyBox/candy;
-
- // Calculate candy boxes per carton
- int numCboxes = carton/candyBox;
-
- // Calculate wasted carton space
- double space = carton%candyBox;
-
- cout << endl
- << "There are " << numCandies
- << " candies per candy box"
- << endl
- << "For the standard boxes there are " << numCboxes
- << " candy boxes per carton " << endl << "with "
- << space << " cubic inches wasted.";
-
- cout << endl << endl << "CUSTOM CANDY BOX ANALYSIS (No Waste)";
-
- // Try the whole range of custom candy boxes
- for(double length = 3.0 ; length <= 7.5 ; length += 0.5)
- for(double width = 3.0 ; width <= 5.0 ; width += 0.5)
- for(double height = 1.0 ; height <= 2.5 ; height += 0.5)
- {
- // Create new box each cycle
- CBox tryBox(length, width, height);
-
- if(carton% tryBox < tryBox.Volume() &&
- tryBox % candy == 0.0 && tryBox/candy >= 30)
- cout << endl << endl
- << "Trial Box L = " << tryBox.GetLength()
- << " W = " << tryBox.GetWidth()
- << " H = " << tryBox.GetHeight()
- << endl
- << "Trial Box contains " << tryBox / candy <<" candies"
- << " and a carton contains " << carton / tryBox
- << " candy boxes.";
- }
- cout << endl;
- return 0;
- }
让我们首先来看该程序的结构。该程序被分为好几个文件,这在C++(www.cppentry.com)编程(www.cppentry.com)中很常见。如果切换到Solution Explorer选项卡(见图8-13),我们将能够看到这些文件。
|
| (点击查看大图)图 8-13 |
Ex8_08.cpp文件包含main()函数和嵌入BoxOperators.h头文件的#include指令,而BoxOperators.h头文件包含BoxOperators.cpp文件中所有函数的原型(它们不是类成员)。Ex8_08.cpp文件还包含一条嵌入Box.h文件中CBox类定义的#include指令。C++(www.cppentry.com)控制台程序通常被分为好几个文件,它们各自属于下列三个基本类别之一:
(1) 包含库文件#include指令、全局常量和变量、类定义以及函数原型的.h文件。换句话说,.h文件包含除可执行代码以外的一切。它们还包含内联函数的定义。当程序中有多个类定义时,我们通常将这些类分别放入单独的.h文件中。
(2) 包含程序的可执行代码的.cpp文件,其中还包含可执行代码所需全部定义的#include指令。
(3) 包含main()函数的另一个.cpp文件。
对main()函数中的代码实际上不需要什么解释-- 它们几乎就是对问题定义的直接文字表示,因为是类接口中的运算符对CBox对象执行面向问题的动作。
使用标准箱子这个问题的答案在main()函数开始部分的两条声明语句中,那两条语句将我们所需的答案计算出来作为初始化数值。然后,我们输出这两个数值,输出时添加了一些解释性的注释。
该问题的第二部分是使用3个嵌套的for循环解决的。这些循环在m_Length、m_Width和m_Height的允许范围内迭代,从而评估所有可能的组合。我们可以将这些组合全部输出到屏幕上,但因为涉及的组合多达200个,而我们可能只对其中一小部分感兴趣,所以程序中使用一条if语句来识别那些我们感兴趣的选项。仅当纸板箱中没有浪费的空间、当前试验的糖果盒中没有浪费的空间,并且该糖果盒至少包含30块糖果时,if表达式才是true。
该程序的输出如下:
- There are 42 candies per candy box
- For the standard boxes there are 144 candy boxes per carton
- with 648 cubic inches wasted.
-
- CUSTOM CANDY BOX ANALYSIS (No Waste)
-
- Trial Box L = 5 W = 4.5 H = 2
- Trial Box contains 30 candies and a carton contains
216 candy boxes. -
- Trial Box L = 5 W = 4.5 H = 2
- Trial Box contains 30 candies and a carton contains
216 candy boxes. -
- Trial Box L = 6 W = 4.5 H = 2
- Trial Box contains 36 candies and a carton contains
180 candy boxes. -
- Trial Box L = 6 W = 5 H = 2
- Trial Box contains 40 candies and a carton contains
162 candy boxes. -
- Trial Box L = 7.5 W = 3 H = 2
- Trial Box contains 30 candies and a carton contains
216 candy boxes.
因为嵌套循环中既评估长5英寸、宽4.5英寸的箱子,也评估长4.5英寸、宽5英寸的箱子,所以我们得到一个重复的解决方案。因为CBox类的构造函数能够确保长度不小于宽度,所以这两个答案是相同的。我们可以添加某种避免出现重复方案的逻辑,但这样做几乎看不到有什么价值。如果愿意,您可以将其当作一道练习题试一下。