📄 unit1.pas
字号:
Eqs[0] := Eqs[y];
Eqs[y] := EqForSwap;
tmpEquation := @Eqs[0];
_Num1 := tmpEquation^.Nums[0]; //第一个未知数的系数
setLength(Result, UnknownCount);
If UnknownCount = 1 Then Begin //如果未知数只剩一个,取其解
Result[0].Numerator := -tmpEquation^.Constant;
Result[0].Denominator := _Num1;
Fraction_Simplify(Result[0]);
Exit;
End Else Begin //方程数或未知数个数不为一,进行加减消元,将化简后的方程组作为GetUnknownOfEquations的参数,递归调用
setLength(MyEqs, l - 1); //消元后的方程组,方程数目为原方程组方程数目减一,因为消掉了一个未知数
setLength(MySolves, UnknownCount - 1);
For x := 0 To l - 2 Do Begin //生成新方程组
tmpEquation1 := @Eqs[x + 1]; //对于Equations来说,x=1 to l-1
_Num2 := tmpEquation1^.Nums[0];
tmpEquation2 := @MyEqs[x];
setLength(tmpEquation2^.Nums, UnknownCount - 1); //化简后的方程组,每个方程未知数数目为原方程组未知数数目减一,因为消掉了一个未知数
If _Num2 = 0 Then Begin //第一个未知数的系数为0,不用化简
For y := 1 To UnknownCount - 1 Do
tmpEquation2^.Nums[y - 1] := tmpEquation1^.Nums[y]; //传递各未知数系数
tmpEquation2^.Constant := tmpEquation1^.Constant; //传递各常量系数
End Else Begin
_Num3 := Fraction_MinMultiple(_Num1, _Num2);
_Multiple1 := _Num3 Div _Num1;
_Multiple2 := _Num3 Div _Num2;
For y := 1 To UnknownCount - 1 Do
tmpEquation2^.Nums[y - 1] := tmpEquation^.Nums[y] * _Multiple1 - tmpEquation1^.Nums[y] * _Multiple2; //对未知数进行加减消元
tmpEquation2^.Constant := tmpEquation^.Constant * _Multiple1 - tmpEquation1^.Constant * _Multiple2; //对系数进行加减消元
End;
End;
MySolves := GetUnknownsOfEquations(MyEqs, UnknownCount - 1); //递归调用,求新方程的解
For x := 1 To UnknownCount - 1 Do
Result[x] := MySolves[x - 1]; //将解赋予Result
RNum := Fraction_CreateOne(0, 1); //RNum=0,分子为0
RNum := Fraction_Minus(RNum, Fraction_CreateOne(tmpEquation.Constant, 1)); //将系数移到方程右边
For x := 0 To UnknownCount - 2 Do //将求出的未知数移到方程右边,求被消掉的未知数
RNum := Fraction_Minus(RNum, Fraction_Multiplination(Fraction_CreateOne(tmpEquation^.Nums[x + 1], 1), MySolves[x]));
Result[0] := Fraction_Division(RNum, Fraction_CreateOne(_Num1, 1)); //见RNum的定义说明
End;
End;
Procedure MakeSolvesInteger; //将分数表示的反应物或生成物的系数通分化为整数
Var
x : Integer;
MinMultiple : Integer;
Begin
MinMultiple := 1;
For x := 0 To AllCou - 1 Do
Fraction_Simplify(FractionSolves[x]); //化简
For x := 0 To AllCou - 1 Do //求所有分母的最小公倍数
MinMultiple := Fraction_MinMultiple(MinMultiple, FractionSolves[x].Denominator);
For x := 0 To AllCou - 1 Do //将分数化为整数
Actors[x].Num := FractionSolves[x].Numerator * MinMultiple Div FractionSolves[x].Denominator;
End;
Begin
setLength(FractionSolves, AllCou); //有AllCou个未知数
FractionSolves := GetUnknownsOfEquations(Equations, AllCou); //解方程,将分数解存入FractionSolves
MakeSolvesInteger; //将分数解通分,化为整数解
End;
////
Procedure TBalancer.MyInitialization; //进行初始化
Var
i : Integer;
Begin
ReactorsCou := FormMain.EditReactor.Lines.Count; //反应物数目
OutPutCou := FormMain.EditOut.Lines.Count; //生成物数目
AllCou := ReactorsCou + OutPutCou; //总数目
setLength(Actors, AllCou);
For i := 0 To ReactorsCou - 1 Do Begin //获取反应物化学式
Actors[i].Str := FormMain.EditReactor.Lines.Strings[i];
Actors[i].IsReactor := true; //是反应物
End;
For i := ReactorsCou To AllCou - 1 Do Begin //获取生成物化学式
Actors[i].Str := FormMain.EditOut.Lines.Strings[i - ReactorsCou];
Actors[i].IsReactor := False; //是生成物
End;
End;
//////////////////////////Fraction////////////////////////
Function TBalancer.Fraction_MinMultiple(Num1, Num2 : Integer) : Integer; //获得两数的最小公倍数,同时进行防错处理
Var
i : Integer;
IsNegative : Boolean;
Begin
If (Num1 < 0) Or (Num2 < 0) Then //是否两数中其一为负
IsNegative := true
Else
IsNegative := False;
Num1 := Abs(Num1); //化为正整数,取绝对会值
Num2 := Abs(Num2);
i := Fraction_MaxDivisor(Num1, Num2);
If i = 0 Then
Result := 0
Else
Result := Num1 * Num2 Div i;
If IsNegative = true Then
Result := -Result;
{算法
如果Num1,Num2的最大公约数为i
则Num1,Num2的最小公倍数为
i*(Num1/i)*(Num2/i)=Num1*Num2 div i
}
End;
Function TBalancer.Fraction_MaxDivisor(Num1, Num2 : Integer) : Integer; //获得两数的最大公约数,同时进行防错处理
Var
IsNegative : Boolean;
Begin
If (Num1 < 0) Or (Num2 < 0) Then //是否两数中其一为负
IsNegative := true
Else
IsNegative := False;
Num1 := Abs(Num1); //化为正整数,取绝对会值
Num2 := Abs(Num2);
If (Num1 = 0) Or (Num2 = 0) Then Begin
Result := 1;
Exit;
End;
While Num1 <> Num2 Do //辗转相减法求最大公约数
If Num1 > Num2 Then
Num1 := Num1 - Num2
Else If Num1 < Num2 Then
Num2 := Num2 - Num1;
If IsNegative = true Then
Result := -Num1
Else
Result := Num1;
End;
Procedure TBalancer.Fraction_Simplify(Var Num : TFraction); //对分数进行化简
Var
i : Integer;
Begin
i := Fraction_MaxDivisor(Num.Numerator, Num.Denominator); //得到分子分母的最大公约数i
Num.Numerator := Num.Numerator Div i; //同除i
Num.Denominator := Num.Denominator Div i;
End;
Function TBalancer.Fraction_Minus(Num1, Num2 : TFraction) : TFraction; //两分数相减
Begin
Result := Fraction_CreateOne
(Num1.Numerator * Num2.Denominator - Num2.Numerator * Num1.Denominator, Num1.Denominator * Num2.Denominator);
Fraction_Simplify(Result); //化简
End;
Function TBalancer.Fraction_Multiplination(Num1, Num2 : TFraction) : TFraction; //两分数相乘
Begin
Result := Fraction_CreateOne(Num1.Numerator * Num2.Numerator, Num1.Denominator * Num2.Denominator);
End;
Function TBalancer.Fraction_Division(Num1, Num2 : TFraction) : TFraction; //两分数相除,Num1/Num2
Begin
Result := Fraction_CreateOne(Num1.Numerator * Num2.Denominator, Num1.Denominator * Num2.Numerator);
End;
Function TBalancer.Fraction_CreateOne(Numerator, Denominator : Integer) : TFraction; //生成一个分数
Begin
Result.Numerator := Numerator; //取分子数
Result.Denominator := Denominator; //取分母数
End;
////////////////////////////////////////////////////////////////////////////////
Initialization //初始化
Elements := TStringList.Create;
With Elements Do Begin //按字母顺序添加元素
Add('Ag');
Add('Al');
Add('Ar');
Add('As');
Add('At');
Add('Au');
Add('B');
Add('Ba');
Add('Be');
Add('Bi');
Add('Br');
Add('C');
Add('Ca');
Add('Cd');
Add('Ce');
Add('Cl');
Add('Co');
Add('Cr');
Add('Cs');
Add('Cu');
Add('Dy');
Add('Er');
Add('Eu');
Add('F');
Add('Fe');
Add('Fr');
Add('Ga');
Add('Gd');
Add('Ge');
Add('H');
Add('He');
Add('Hf');
Add('Hg');
Add('Ho');
Add('I');
Add('In');
Add('Ir');
Add('K');
Add('Kr');
Add('La');
Add('Li');
Add('Lu');
Add('Mg');
Add('Mn');
Add('Mo');
Add('N');
Add('Na');
Add('Nb');
Add('Nd');
Add('Ne');
Add('Ni');
Add('O');
Add('Os');
Add('P');
Add('Pb');
Add('Pd');
Add('Pm');
Add('Po');
Add('Pr');
Add('Pt');
Add('Ra');
Add('Rb');
Add('Re');
Add('Rh');
Add('Rn');
Add('Ru');
Add('S');
Add('Sb');
Add('Sc');
Add('Se');
Add('Si');
Add('Sm');
Add('Sn');
Add('Sr');
Add('Ta');
Add('Tb');
Add('Tc');
Add('Te');
Add('Ti');
Add('Tl');
Add('Tm');
Add('V');
Add('W');
Add('Xe');
Add('Y');
Add('Yb');
Add('Zn');
Add('Zr');
Sort; //其实已排好序了
End;
{ 如:
在Elements 寻找As元素,返回序号为3 //序号从零开始
则As元素的式量为 MOfElements[3+1]=75
}
MOfElements[1] := 108; //Ag
MOfElements[2] := 27; //Al
MOfElements[3] := 40; //Ar
MOfElements[4] := 75; //As
MOfElements[5] := 210; //At
MOfElements[6] := 197; //Au
MOfElements[7] := 11; //B
MOfElements[8] := 137; //Ba
MOfElements[9] := 9; //Be
MOfElements[10] := 209; //Bi
MOfElements[11] := 80; //Br
MOfElements[12] := 12; //C
MOfElements[13] := 40; //Ca
MOfElements[14] := 112; //Cd
MOfElements[15] := 140; //Ce
MOfElements[16] := 35.5; //Cl
MOfElements[17] := 59; //Co
MOfElements[18] := 52; //Cr
MOfElements[19] := 133; //Cs
MOfElements[20] := 64; //Cu
MOfElements[21] := 162.5; //Dy
MOfElements[22] := 167; //Er
MOfElements[23] := 152; //Eu
MOfElements[24] := 19; //F
MOfElements[25] := 56; //Fe
MOfElements[26] := 223; //Fr
MOfElements[27] := 70; //Ga
MOfElements[28] := 157; //Gd
MOfElements[29] := 73; //Ge
MOfElements[30] := 1; //H
MOfElements[31] := 4; //He
MOfElements[32] := 178.5; //Hf
MOfElements[33] := 200.6; //Hg
MOfElements[34] := 165; //Ho
MOfElements[35] := 127; //I
MOfElements[36] := 115; //In
MOfElements[37] := 192.2; //Ir
MOfElements[38] := 39; //K
MOfElements[39] := 84; //Kr
MOfElements[40] := 139; //La
MOfElements[41] := 7; //Li
MOfElements[42] := 175; //Lu
MOfElements[43] := 24; //Mg
MOfElements[44] := 55; //Mn
MOfElements[45] := 96; //Mo
MOfElements[46] := 14; //N
MOfElements[47] := 23; //Na
MOfElements[48] := 93; //Nb
MOfElements[49] := 144; //Nd
MOfElements[50] := 20; //Ne
MOfElements[51] := 59; //Ni
MOfElements[52] := 16; //O
MOfElements[53] := 190; //Os
MOfElements[54] := 31; //P
MOfElements[55] := 207; //Pb
MOfElements[56] := 106; //Pd
MOfElements[57] := 145; //Pm
MOfElements[58] := 209; //Po
MOfElements[59] := 141; //Pr
MOfElements[60] := 195; //Pt
MOfElements[61] := 226; //Ra
MOfElements[62] := 85.5; //Rb
MOfElements[63] := 186; //Re
MOfElements[64] := 103; //Rh
MOfElements[65] := 222; //Rn
MOfElements[66] := 101; //Ru
MOfElements[67] := 32; //S
MOfElements[68] := 122; //Sb
MOfElements[69] := 45; //Sc
MOfElements[70] := 79; //Se
MOfElements[71] := 28; //Si
MOfElements[72] := 150; //Sm
MOfElements[73] := 119; //Sn
MOfElements[74] := 88; //Sr
MOfElements[75] := 181; //Ta
MOfElements[76] := 159; //Tb
MOfElements[77] := 98; //Tc
MOfElements[78] := 128; //Te
MOfElements[79] := 48; //Ti
MOfElements[80] := 204; //Tl
MOfElements[81] := 169; //Tm
MOfElements[82] := 51; //V
MOfElements[83] := 184; //W
MOfElements[84] := 131; //Xe
MOfElements[85] := 89; //Y
MOfElements[86] := 173; //Yb
MOfElements[87] := 65; //Zn
MOfElements[88] := 91; //Zr
Finalization
Elements.Free;
End.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -