所以我有一块代码,我觉得可以写得更好。基本上它是一个简单的欧姆定律计算器,它根据输入变量2的用户输出4变量。我只是想知道如何减少给定变量的重复计算。我知道它应该能够完成,但我无法想到如何去做。
这里是onclick事件的代码,你会注意到根据用户的输入,一些unknowen和knowen变量将被重新计算多达4-5次,如果那么 else <我可以填充代码块/ strong>陈述,但我想尝试并提出建议并找到简单的解决方案/想法。
注意:我不是一名专业程序员,只是心理障碍的一个爱好如何减少重新计算。基本上寻找想法如何检测可能的4中的哪个变量已被输入
procedure TForm1.btnCalcClick(Sender: TObject);
var
fVolt, fAmp, fResist, fWatt, fBattLife, fBattMah: Single;
begin
// ============ Set all variables to 0 =====================
fVolt := 0;
fAmp := 0;
fResist := 0;
fWatt := 0;
fBattLife := 0;
fBattMah := 0;
// ========= Input initial variables =======================
if lblVolts.Text <> '' then
fVolt := StrToFloat(lblVolts.Text);
if lblAmps.Text <> '' then
fAmp := StrToFloat(lblAmps.Text);
if lblResistance.Text <> '' then
fResist := StrToFloat(lblResistance.Text);
if lblWatts.Text <> '' then
fWatt := StrToFloat(lblWatts.Text);
if lblBattMah.Text <> '' then
fBattMah := StrToFloat(lblBattMah.Text);
// ================== Ohms Law =============================
if ((fVolt > 0) and (fResist > 0)) then
begin
fAmp := fVolt / fResist;
fWatt := fVolt * fAmp;
end;
if ((fVolt > 0) and (fWatt > 0)) then
begin
fAmp := fWatt / fVolt;
fResist := fVolt / fAmp;
end;
if ((fVolt > 0) and (fAmp > 0)) then
begin
fWatt := fVolt * fAmp;
fResist := fVolt / fAmp;
end;
if ((fAmp > 0) and (fResist > 0)) then
begin
fVolt := fResist * fAmp;
fWatt := fVolt * fAmp;
end;
if ((fAmp > 0) and (fWatt > 0)) then
begin
fVolt := fWatt / fAmp;
fResist := fVolt / fAmp;
end;
if ((fResist > 0) and (fWatt > 0)) then
begin
fVolt := Sqrt(fWatt * fResist);
fAmp := fWatt / fVolt;
end;
// ================= Calculat Battery Life ===================
if ((fBattMah > 0) and (fAmp > 0)) then
begin
fBattLife := ((fBattMah / 1000) / Power(fAmp, 1.25));
lblBattLife.Text := FormatFloat('0.00 Hrs', fBattLife);
end;
// ================ Display Results ==========================
if ((fVolt > 0) and (fAmp > 0) and (fResist > 0) and (fWatt > 0)) then
begin
lblVolts.Text := FormatFloat('0.0', fVolt);
lblAmps.Text := FormatFloat('0.00', fAmp);
lblResistance.Text := FormatFloat('0.0', fResist);
lblWatts.Text := FormatFloat('0.00', fWatt);
end;
end;
答案 0 :(得分:0)
我提供了三种方法可以解决这个问题,但我会把编码留给你。
首先,我同意David Heffernan上面所说的话。
创建一个包含6个元素的记录(或类);从表单中读取值到记录中(假设,例如,-1表示缺少值);调用计算缺失值的(单个)方法;使用所有值更新表单。
就内部结构而言,我经常发现在电子表格如何工作方面考虑这样的问题会很有帮助。尝试在Excel中解决它,然后在您的代码中重现它。
第二种方法是将一些逻辑移入GUI并将几种特定方法添加到记录/类中。当您单击“计算”按钮时,它会查看您提供的两个值,然后调用一个方法来获取这两个特定变量并计算其余变量。这会产生一些荒谬的公共方法和一些更私有的方法,尽管方法中的计算都非常简单。
或者,您可以使GUI逻辑更加通用,并根据输入的两个变量首先求解欧姆定律(E = IR)或幂方程(P = IE)。然后解决剩下的问题。你可能需要三种公共方法,以及一些私有方法。对于您的特定问题,我认为这可能是最佳方法。
FWIW,我前段时间写了一个Delphi应用程序,它有几十个像这样的交互变量(在多个级别上),我发现像内部电子表格一样构建它比我试过的其他方法更容易维护。是的,您最终可能会进行一些冗余计算。但问题不在于这种情况下的速度;如果您没有一些很好的方法来组织程序中的计算,那么您将会失去理智,试图修复错误或稍后扩展代码。
无论你如何解决它,你必须有一些逻辑来确定你开始的值,然后需要调用哪些方程以及按什么顺序。您可以将一些分析逻辑移动到GUI中,这反映在记录/类的特定方法或一般方法的最终方式 - 一个全能方法,一些通用方法或一堆特定方法。最后,您将为同一组输入变量执行相同的计算集。你无法解决这个问题。可变性将取决于您如何调用这些计算。
答案 1 :(得分:0)
如果你的问题确实是'如何进行速度优化?'当你在寻找速度优化时if / then / else没有任何问题。下面的代码保证计算只进行一次!这是IS速度优化。
procedure TForm1.btnCalcClick(Sender: TObject);
var
fVolt, fAmp, fResist, fWatt, fBattLife, fBattMah: Single;
begin
// ========= Input initial variables =======================
fVolt := StrToFloatDef(lblVolts.Text, 0);
fAmp := StrToFloatDef(lblAmps.Text, 0);
fResist := StrToFloatDef(lblResistance.Text, 0);
fWatt := StrToFloatDef(lblWatts.Text, 0);
fBattMah := StrToFloatDef(lblBattMah.Text, 0);
// ================== Ohms Law =============================
if (fVolt > 0) then
if (fResist > 0)) then
begin
fAmp := fVolt / fResist;
fWatt := fVolt * fAmp;
end
else
if (fWatt > 0) then
begin
fAmp := fWatt / fVolt;
fResist := fVolt / fAmp;
end
else
if (fAmp > 0) then
begin
fWatt := fVolt * fAmp;
fResist := fVolt / fAmp;
end
else
else
if (fAmp > 0) then
if (fResist > 0))
begin
fVolt := fResist * fAmp;
fWatt := fVolt * fAmp;
end
else
if (fWatt > 0) then
begin
fVolt := fWatt / fAmp;
fResist := fVolt / fAmp;
end
else
else
if ((fResist > 0) and (fWatt > 0)) then
begin
fVolt := Sqrt(fWatt * fResist);
fAmp := fWatt / fVolt;
end
else
else
begin
ShowMessage('Error');
EXIT;
end;
// ================= Calculat Battery Life ===================
if (fBattMah > 0) then
begin
fBattLife := ((fBattMah / 1000) / Power(fAmp, 1.25));
lblBattLife.Text := FormatFloat('0.00 Hrs', fBattLife);
end;
// ================ Display Results ==========================
if ((fVolt > 0) and (fAmp > 0) and (fResist > 0) and (fWatt > 0)) //You should be able to get rid of this.
then
begin
lblVolts.Text := FormatFloat('0.0', fVolt);
lblAmps.Text := FormatFloat('0.00', fAmp);
lblResistance.Text := FormatFloat('0.0', fResist);
lblWatts.Text := FormatFloat('0.00', fWatt);
end
else
ShowMessage('Error');
end;
我没有尝试编译代码。正如其他人建议的那样,您也可以将算法与GUI分开。使用这样的记录传递参数:
type
MyRec= record
fVolt,
fAmp,
fResist,
fWatt,
fBattLife,
fBattMah: Single;
end;