我正在尝试构建一个求解器对象。它打算执行的算法是:
其他一些约束
ay
和az
描述),但是它们需要扩展为完整的50个元素用于矩阵计算。因此,求解器对象具有内部A数组(保持扩展形式)ay
,az
和b
存储为对象foo
的元素的客户端代码,因此具有一个foo
的数组比持有ay
,az
和b
的几个数组。这种架构是不可协商的,这意味着:
doEverything(double *ay, double *az, double *b)
foo::b
元素是不可接受的)我目前的课程要求正确使用以下公共职能:
void prepForInputWith(int nElements)
- 调整内部数组的大小以允许nElements的空间(调用一次)
void setAandB(double ay, double az, double b)
- 设置A和b中的下一行数据(每个数据点调用一次)void calculateXBestFit()
- 将系统反转为x(称为一次)double returnBPrime()
- 返回下一个单元格的答案(每个数据点调用一次,并且必须以与setNextResult相同的顺序调用)请注意,客户必须按照调用returnBPrime()
的顺序调用setAandB()
,因为A的条目(在setAandB()
中计算并在calculateXBestFit()
中使用)在returnBPrime()
中计算b' = Ax时重复使用。删除此优化将使returnBPrime()
可以按任何顺序调用,但会带来运行时惩罚。
我对此感到不满,因为:
在这种方法中,doEverything()
方法中可以理所当然的一些事情是不可能的:
returnBPrime()
returnBPrime()
可以被称为与setAandB()
这意味着
有更优雅的方式吗?
答案 0 :(得分:0)
这个类的接口规范似乎对类的客户端可以调用其函数的顺序设置了一些约束(如果他们希望得到有效的结果)。我无法想到在编译时强制执行该序列的任何方法。
您可以做的不是访问超出范围的数据。您显然需要某种内部计数器来说明setAandB()
修改或返回每个数组的哪个元素
和returnBPrime()
。事实上,我会让这些功能中的每一个使用不同的计数器,
我会让calculateXBestFit()
将这两个计数器设置为零。
然后,对nElements
的下一次returnBPrime()
来电将返回b'的元素。按顺序,您可以拨打setAandB()
另一个nElements
以准备下一个电话
到calculateXBestFit()
。
有一些有用的运行时检查,但我认为它们的成本相当低。主要的一个
是范围检查returnBPrime()
使用的计数器。一旦达到b'中存储的数据的长度,后续的呼叫就不会尝试读取b' (但如果您可以就此达成一致,可能会生成异常或错误消息),直到下一次调用calculateXBestFit()
之后。只要此类的客户端持有合同,此运行时检查的成本就是if (counter < limit)
形式的分支的成本。
还有setAandB()
的运行时检查,但我认为你已经考虑了一个(因为你说如果需要的话,类会重新调整数组的大小)。
在calculateXBestFit()
设置每个数组的所有nElements
元素之前,如果调用了setAandB()
,您需要达成一致。在我看来,最好的行为是将setAandB()
的调用次数视为所需的数组大小,而不管nElements
的值是多少。这也意味着要记住calculateXBestFit()
使用的数组的大小,以便returnBPrime()
将使用该数字,而不是nElements
,作为实际允许从b读取的值的数量&# 39;
顺便说一下,我还要calculateXBestFit()
计算并存储b&#39;的内容。在此对象的另一个数组中。这意味着此次调用后对象发生的任何事情 - 除了对calculateXBestFit()
的另一次调用 - 都不会影响对returnBPrime()
的调用结果。
让我们看一下:这涵盖了多次调用setAandB()
,调用setAandB()
太少次,调用returnBPrime()
太多次,甚至将调用交错到{{ 1}}调用returnBPrime()
以解决下一个问题。关于我能想到的唯一剩下的明显错误是调用setAandB()
太少次,结果就是客户端获得的数据少于本来应该的数据。我只看到一个你还没有承诺的运行时检查。